Питання Отримайте розміри екрана в пікселях


Я створив кілька спеціальних елементів, і я хочу програмно розмістити їх у верхньому правому куті (n пікселі з верхнього краю і m пікселі з правого краю). Тому мені потрібно отримати ширину екрана та висоту екрана, а потім встановити позицію:

int px = screenWidth - m;
int py = screenHeight - n;

Як я можу отримати screenWidth і screenHeight в основній діяльності?


1672
2018-06-19 08:25


походження


Використовуйте dp замість px. тому що це спотворить макет з іншими пристроями .. - Nepster
Не забудьте помножити на getResources (). GetDisplayMetrics (). Щільність для обліку масштабування зображення - jmaculate
Це свідчить про те, що найпопулярніша відповідь не завжди найкраща (і багато людей повторюють відповіді на запитання). Замість того, щоб getSize і застарілі комбінації getWidth / getHeight (ігноруючи помилки), спробуйте Balaji.K getMetrics. Коментар Ніка у його відповіді навіть пояснює getDisplayMetrics розглянути розмір рядка системи / стану. Також ви можете використовувати щільність як jmaculate і LoungeKatt пояснити, щоб мати EXACT значення:DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels; Перевірено в Android v2.2 (API 8) і v4.0 з хорошими результатами та немає помилок / попереджень. - Armfoot
Displaymetrics displaymetrics = нові DisplayMetrics (); getWindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int висота = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; - Azahar


Відповіді:


Якщо ви хочете використовувати розміри дисплея в пікселях getSize:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

Якщо ви не в одній Activity ви можете отримати за замовчуванням Display через WINDOW_SERVICE:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

Раніше getSize був введений (на рівні API 13), ви могли б використовувати getWidth і getHeight методи, які зараз застаріли:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

Проте для випадку використання, який ви описуєте, маржа / пробіли в макеті виглядають більш доречним.

Інший спосіб: DisplayMetrics

Структура, яка описує загальну інформацію про дисплей, таку як його розмір, щільність та масштабування шрифтів. Щоб отримати доступ до учасників DisplayMetrics, ініціалізуйте такий об'єкт:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Ми можемо використовувати widthPixels отримати інформацію для:

"Абсолютна ширина дисплея в пікселях".

Приклад:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);

3328
2018-06-19 08:41



developer.android.com/reference/android/view/Display.html - gcb
getWidth () або getSize ()? Що я буду використовувати, якщо мені потрібен моє додаток для роботи з API <13, а також API> 13? - Carol
спробуйте {display.getSize (розмір); width = size.x; height = size.y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); } - Arnaud
Я не розумію, чому ви хочете використовувати try/catch за таку перевірку? Чому б не просто користуватися if (android.os.Build.VERSION.SDK_INT >= 13) без будь-якого виключеного винятку взагалі? Я думаю try/catch в звичайному прикладі потоку як погану практику. - CipherCom
що робити, якщо ви хочете отримати розмір екрану за винятком панелі навігації та / або панелі сповіщень - android developer


Один із способів:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Вона застаріла, і вам слід спробувати наступний код. Перші два рядки коду надають вам об'єкт DisplayMetrics. Ці об'єкти містять поля, такі як heightPixels, widthPixels.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;

350
2018-01-31 02:01



Зауважте, що показники (ширина, висота) змінюються залежно від обертання пристрою. - Tony Chan
Метрики повертають розмір дисплея, але HoneyComb і вище, у вашій діяльності буде менше місця, ніж те, що повертається через системний рядок. - Guy
@Guy це залежить від вашої реалізації. Ви можете сховати рядок стану: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - Hagai L
Також існує такий спосіб: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels - Nik
остаточна плаваюча шкала = getResources (). getDisplayMetrics (). щільність; int ширина = (int) (metrics.widthPixels * scale + 0.5f); - Ви повинні відповідати за щільність пристрою, коли робите це таким чином. - Abandoned Cart


Він може не відповісти на ваше запитання, але це може бути корисно знати (я сам шукав його, коли я опинився на цьому питанні), що якщо вам потрібен параметр View, але ваш код виконується, коли його макет ще не викладено (наприклад, в onCreate() ) ви можете встановити a ViewTreeObserver.OnGlobalLayoutListener з View.getViewTreeObserver().addOnGlobalLayoutListener() і покладіть відповідний код, який потребує розмір перегляду там. Зворотний дзвінок слухача буде викликаний, коли макет буде викладено.


111
2018-04-06 21:23



або просто напишіть view.post - Lukas Hanacek
сутність для швидкої реалізації :) gist.github.com/doridori/9208247 - Dori
view.post не гарантує роботу, хоча. Це просто обхідний шлях. - marsbear
@marsbear де це говорить View.post() не гарантовано працювати? Мені цікаво, тому що я також покладаюся на цей метод для отримання розміру вигляду після макета і не знав, що він ненадійний. - Tony Chan
@ Turbo Я кажу що: p Ми використали цей обхід раніше, і це виявилося ненадійним. Це рішення полягає в припущенні, що спочатку макетування виконується в межах того самого повороту UIThread, як ініціалізація. Отже, ви можете запланувати виконання вашого коду перед чергуванням користувацького інтерфейсу через повідомлення (), і це буде добре. Виявилося, що при певних обставинах макетування може тривати навіть довше, і вигляд все ще не викривлюється, коли випущений код виконується. Що я зараз роблю, додайте ViewTreeObserver в onCreate і видаліть його після першого onLayout. Увімкніть свої матеріали під час першого вкладок. - marsbear


(Відповідь 2012 року може бути застарілою) Якщо ви хочете підтримати pre Honeycomb, вам доведеться встановити зворотну сумісність до API 13. Щось подібне:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

Зрештою, застарілі методи зрештою будуть вилучені з самих останніх SDK, але поки ми все-таки покладаємось на більшість наших користувачів, які мають ОС Android 2.1, 2.2 і 2.3, це ми залишаємо.


103
2017-07-24 03:14



Так, це було ще в 2012 році. - digiphd
вибачте, дозвольте мені пояснити, що я мав на увазі. Дуже малоймовірно, щоб кожен підтримував API <14 від 22.06.2015 - sudocoder


Я спробував всі можливі "рішення" безуспішно, і я помітив, що приклад програми "Dalvik Explorer" Елліотта Хьюза завжди відображає правильний розмір на будь-якій версії пристрою / ОС Android. Я опинився на його проекті з відкритим кодом, який можна знайти тут: https://code.google.com/p/enh/

Ось весь відповідний код:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDIT: трохи покращена версія (уникайте стрілянини винятків на непідтримуваній версії ОС):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

62
2018-03-29 08:15



Це єдиний пост, який враховує прикраси вікон (панель стану / панель меню). працював чудово для мене. - Andy Cochrane
Чудово, однак, ви ніколи не повинні очікувати винятків із вогню бізнес-логіки. Виняток стрільби (навіть коли це спіймано) є жахливим для виконання. Крім того, ви виконуєте більше роботи, ніж потрібно, якщо SDK_INT становить> 13. Натомість вам слід просто додати деякі елементи ifs на Build.VERSION.SDK_INT. - Erik B
@ Ерік Б, я згоден. Я додав удосконалену версію. Тим не менш, я залишив частину "від SDK 1", якщо у випадку спроби / зловити щось йде не так (я бачив багато поганих речей в Android, особливо якщо ви вважаєте, що неможливо щось іти не так, тому я люблю зберігати його безпечно :)) . У будь-якому випадку там не повинно бути занадто мого накладних витрат, тому що цей розрахунок слід виконувати лише один раз (наприклад, значення можуть зберігатися в деяких статичних атрибутах). - Dragan Marjanović
Зауважте, що цей код є ліцензованим під GPL v3, який має наслідки для використання в додатках для виробництва. - TalkLittle
GPL та залежно від методів відображення до викликів, які можуть не бути присутніми в майбутніх версіях Android. Мххх - Michel


Щоб отримати доступ до висоти рядка стану для пристроїв Android, ми віддаємо перевагу програмі, щоб отримати це:

Зразок коду

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

Перемінна result дає висоту в пікселі.

Для швидкого доступу

Enter image description here

Для отримання додаткової інформації про висоту Title bar, Navigation bar і Content View, будь ласка, дивіться Розміри екрана пристрою Android.


43
2017-08-27 13:12



Якраз те, що мені потрібно! getResources().getDisplayMetrics().heightPixels + result дає фактичний повноекранний висоту. Відповідь Драгана Мар'яновича також працює, але я віддаю перевагу цьому більш короткому та простішому рішенню. - Michel
Цей підхід застарілий у Android Marshmallow. Висота панелі стану може змінюватися з пристрою або версії Android. Краще використовувати OnApplyWindowInsetsListener. - Heinrich


Найпростіший спосіб:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

42
2017-11-26 10:47



Крім того, єдине з усіх цих рішень, які працювали для мене - ShadowGod
це так. (Y) - Ahsan Sher
Проста функція для того, щоб робити те саме .. Див цей пост whats-online.info/science-and-tutorials/121/... - Daniel Nyamasyo


Спочатку перегляньте (наприклад, по findViewById()), а потім ви можете використовувати getWidth () на самому погляді.


28
2018-06-19 08:38



Це насправді, як документація розповідає вам, що це зробити ... але це нічого не має сенсу, якщо ви НЕ використовуєте вид. ви можете використовувати щось інше, наприклад, mglsurfaceview. - gcb
це краще, оскільки батьківський вигляд не може бути розміром дисплея. Але переконайтеся, що це зроблено в точці, в якій ви переглядаєте запит про розмір, який вже розміщено, який зазвичай не буде розташовано на onCreate (). Ви можете використовувати власний зворотний виклик з onWindowFocusChanged (булевий hasFocus), який буде викликати після того, як всі виміри були переглянуті, і так далі, гарантуючи, що ви не отримаєте неправильні розміри для перегляду, який вас цікавить ... - Dori


У мене є дві функції, одна для передачі контексту, а інша - висота та ширина у пікселях:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

і

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}

24
2017-10-17 14:44



Вам потрібно додати @SuppressLint("NewApi") трохи над символом функції, щоб мати змогу скомпілювати. - Adil Malik
Я думаю, що краще одержувати висоту і ширину замість одного окремого виклику API, оскільки в іншому випадку вони можуть бути не синхронізованими. Це може статися, якщо зміна орієнтації екрана під час роботи вашого коду. - Sam


Для динамічного масштабування за допомогою XML існує атрибут, що називається "android: layout_weight"

Нижче наведено приклад, модифікований за реакцією синіконів на ця нитка, показує кнопку, яка займає 75% екрану (вага = .25), а текстовий перегляд займає 25% екрану (вага = .75).

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>

17
2017-12-22 06:11





Цей код я використовую для завдання:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

Здається досить чистим і поки що, піклується про знецінення.


17
2017-12-27 14:31