Як отримати розміри екрана у вигляді пікселів в Android


1842

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

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

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


Використовуйте dp замість px. тому що це спотворить ваш макет з іншими пристроями ..
Jawad Zeb

Не забудьте помножити на getResources (). GetDisplayMetrics (). Щільність для врахування масштабування дисплея
jmaculate

Це свідчить про те, що відповідь, яка не відповідає голосам, не завжди найкраща (і багато людей повторюють відповіді на відповідь) Замість комбінації getSize та застарілого getWidth / getHeight (ігноруючи помилки), спробуйте Balaji.K's 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 (); getDindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int висота = displaymetrics.heightPixels; int width = displaymetrics.widthPixels;
Азахар

інший спосіб отримати DisplayMetrics: Resources.getSystem().getDisplayMetrics(). Вам не знадобиться Contextїх отримати.
19

Відповіді:


3478

Якщо ви хочете розміри дисплея в пікселях, ви можете використовувати 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();

Якщо ви знаходитесь у фрагменті і хочете активувати це, просто використовуйте Activity.WindowManager (у Xamarin.Android) або getActivity (). GetWindowManager () (на Java).

Перш ніж getSizeбуло запроваджено (на рівні 13 API), ви могли використовувати методи 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);

13
getWidth () або getSize ()? Що б я використав, якщо мені потрібен додаток для роботи на API <13, а також API> 13?
Керрол

52
спробуйте {display.getSize (size); ширина = розмір.x; висота = розмір.y; } catch (NoSuchMethodError e) {width = display.getWidth (); висота = display.getHeight (); }
Арно

248
Я не бачу, чому ви хочете використовувати try/catchдля такої перевірки? Чому б взагалі просто не використати if (android.os.Build.VERSION.SDK_INT >= 13)без викинутого винятку? Я вважаю, try/catchщо звичайний потік додатків є поганою практикою.
Патрік

2
@ A-Live тоді програма також вийде (але не вийде з ладу). Ми, розробники, повинні заздалегідь перевірити нову версію ОС, і це, можливо, просто приховає проблему. Також з цим аргументом можна / слід оточити кожні кілька рядків коду за допомогою try / catch, що, на мою думку, є поганою практикою, як уже згадувалося.
Патрік

11
Що робити, якщо ви хочете отримати розмір екрана, виключаючи панель навігації та / або панель сповіщень
розробник android

374

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

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;

14
Зауважте, що показники (ширина, висота) змінюються залежно від обертання пристрою.
Тоні Чан

8
Метрики повернуть розмір дисплея, але HoneyComb і вище, у вашій діяльності буде менше місця, ніж повернене завдяки системній панелі.
Хлопець

3
@Годай, це залежить від вашої реалізації. Ви можете приховати рядок стану: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Хагай L

79
Існує також такий спосіб: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels
Nik

остаточна плаваюча шкала = getResources (). getDisplayMetrics (). щільність; int width = (int) (metrics.widthPixels * шкала + 0,5f); - Ви повинні враховувати щільність пристрою, роблячи це так.
Покинутий кошик

119

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


або просто напишіть view.post
Лукас Ханачек

view.post хоча не гарантовано працює. Це просто рішення.
marsbear

@marsbear, де сказано View.post(), не гарантовано працювати? Мені цікаво, тому що я також покладаюся на цей метод для отримання розміру представлення після макета, і не знав про це ненадійно.
Тоні Чан

@Turbo Я кажу, що: p Ми раніше використовували це рішення, і воно виявилося ненадійним. Це вирішення базується на припущенні, що початкове компонування виконується в межах того ж звороту UIThread, що і ініціалізація. Отже, ви можете запланувати запуск коду до наступного повороту користувальницького інтерфейсу через post () і будете добре. Виявилося, що макет може зайняти ще довше за певних обставин, і погляд все ще не був розкладений, коли поштовий код запустився. Що я зараз роблю, це додати ViewTreeObserver в onCreate і видалити його після першого onLayout. Запропонуйте свої речі під час першого першого макета.
marsbear

@marsbear чи не має значення, від чого Viewви отримуєте ViewTreeObserver? Або всі вони поділяють одне й те саме?
Тоні Чан

109

(Відповідь 2012 року може бути застарілою) Якщо ви хочете підтримати попередньо 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, це те, що нам залишається.


Так, це було ще у 2012 році.
digiphd

Вибачте, дозвольте мені уточнити, що я мав на увазі. Навряд чи хтось підтримає API <14 станом на 22.06.2015
sudocoder

69

Я безуспішно випробував усі можливі "рішення", і я помітив, що додаток "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) {
}

9
Це єдиний пост, який враховує прикраси вікон (панель стану / панель меню). добре працював для мене.
Енді Кокрайн

5
Дивовижно, проте ви ніколи не повинні очікувати винятків з ділової логіки. Стрільба з винятку (навіть при попаданні) - жахлива для виконання. Крім того, ви робите більше роботи, ніж потрібно, якщо SDK_INT> 13. Натомість вам слід просто додати кілька ifs на Build.VERSION.SDK_INT.
Ерік Б

3
@Erik B, я згоден. Я додав вдосконалену версію. І все-таки я залишив частину "з SDK 1" на всякий випадок, коли щось не вдається в спробі / лові (я бачив багато поганих речей в Android, особливо коли ти вважаєш, що щось неможливо піти не так, тому мені подобається тримати його в безпеці :)) . У будь-якому разі не повинно бути занадто багатоголовкових накладних витрат, оскільки цей розрахунок слід проводити лише один раз (наприклад, значення можуть зберігатися в деяких статичних атрибутах).
Драган Мар’янович

8
Зауважте, що цей код ліцензований під GPL v3, що має наслідки для використання у виробничих додатках.
TalkLittle

GPL та залежно від розмірковування для виклику методів, які можуть бути відсутні у майбутніх версіях Android. Mhhh
Michel

47

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

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

46

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

Зразок коду

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

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

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

Введіть тут опис зображення

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


Тільки те, що мені було потрібно! getResources().getDisplayMetrics().heightPixels + resultдає фактичну висоту екрану. Відповідь Драгана Мар’яновича також працює, але я віддаю перевагу цьому набагато коротшому та простішому рішенню.
Мішель

Цей підхід є застарілим, як для Android Marshmallow. Висота рядка стану може змінюватися в залежності від пристрою або версії Android. Краще використовувати OnApplyWindowInsetsListener.
Генріх

32

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


3
Це насправді, як документація каже вам це зробити ... але це ніби безглуздо, якщо ви НЕ використовуєте подання. ви можете використовувати щось інше, наприклад, mglsurfaceview.
gcb

2
це краще, оскільки батьківський вигляд може бути не розміром дисплея. Але переконайтеся, що це робиться в момент, коли представлений вигляд, на який ви запитуєте розмір, вже був викладений, що, як правило, не знаходиться всередині onCreate (). Ви можете використовувати спеціальний зворотний дзвінок від onWindowFocusChanged (boolean hasFocus), який буде викликаний після того, як всі перегляди будуть виміряні тощо, гарантуючи, що ви не отримаєте неправильних розмірів для перегляду, який вас цікавить ...
Дорі,

27

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

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;
}

Вам потрібно додати @SuppressLint("NewApi")трохи вище підпису функції, щоб мати можливість компілювати.
Аділ Малик

Я думаю, що краще досягти висоти та ширини за один раз, ніж в окремих викликах API, тому що в іншому випадку вони можуть бути не синхронізовані. Це може статися, якщо орієнтація екрана змінюється під час роботи вашого коду.
Сем

17

Для динамічного масштабування за допомогою 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

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

// `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

Це не набагато краще рішення? DisplayMetrics постачається з усім необхідним і працює з API 1.

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

Ви також можете отримати фактичний дисплей (включаючи декори екрана, такі як панель стану або панель навігації по програмному забезпеченню), використовуючи getRealMetrics , але це працює лише для 17+.

Я щось пропускаю?


1
Це не віднімання місця для екранного керування (наприклад, на планшетах або Nexus пристроях). Крім того, я отримую інше значення (750 проти 800) на моєму 10-дюймовому планшеті, залежно від того, чи активність активна під час обчислення. Але для моїх цілей це більш ніж добре. Дякую!
Стівен L

15

Просто додаючи відповідь Франческо. Інший більш підходящий спостерігач, якщо ви хочете дізнатись місце у вікні чи розташування на екрані - ViewTreeObserver.OnPreDrawListener ()

Це також може бути використане для пошуку інших атрибутів представлення, яке в основному невідоме в час onCreate (), наприклад, прокручена позиція, масштабована позиція.


15

Використання наступного коду в розділі Діяльність.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;

15

Знайдіть ширину та висоту екрана:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Використовуючи це, ми можемо отримати останню версію SDK 13.

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}

15
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;


12

Потрібно сказати, що якщо ви перебуваєте не в Activity, а в View(або маєте змінну Viewтипу у вашому обсязі), використовувати не потрібно WINDOW_SERVICE. Тоді можна використовувати як мінімум два способи.

Спочатку:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

Друге:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

Усі ці методи, які ми називаємо тут, не застаріли.


12
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}

11

Для отримання розмірів екрана використовуйте метрики відображення

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

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

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

9

Це не є відповіддю для ОП, оскільки він хотів розмірів дисплея в реальних пікселях. Я хотів розміри в "незалежних від пристрою пікселях", і збираючи відповіді звідси https://stackoverflow.com/a/17880012/253938 і тут https://stackoverflow.com/a/6656774/253938 я придумав з цим:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);

9

Ви можете отримати розмір висоти за допомогою:

getResources().getDisplayMetrics().heightPixels;

і ширину за допомогою

getResources().getDisplayMetrics().widthPixels; 

8

Існує неактуальний спосіб зробити це за допомогою DisplayMetrics (API 1), що дозволяє уникнути безладу спроб / зловити:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;

8

Я б обернув код getSize таким чином:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}

Цей збій відбувається на емуляторі під управлінням Android 4.0 (API 14).
jww

6

Для того, хто шукає доступний розмір екрана без рядка стану та рядка дій (також завдяки відповіді Swapnil):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

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

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}

6

Спочатку завантажте XML-файл, а потім напишіть цей код:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

Показати ширину та висоту відповідно до роздільної здатності екрана.


6

Дотримуйтесь наведених нижче методів:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}

6

Котлін

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}

5

Бувають випадки, коли вам потрібно знати точні розміри наявного простору для макета, коли в активі onCreate. Після деякої думки я опрацював такий спосіб зробити це.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

Якщо з якоїсь причини ви не хочете додавати іншу активність до маніфесту Android, ви можете це зробити так:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    

Очевидно, ви також можете передати висоту назад в пачці.
Стів Варінг

5

Якщо ви не хочете, щоб накладні витрати WindowManagers, Points або Displays, ви можете захопити атрибути висоти та ширини найвищого елемента перегляду у вашому XML, за умови, що його висота та ширина встановлені на match_parent. (Це справедливо до тих пір, поки ваш макет займає весь екран.)

Наприклад, якщо ваш XML починається з подібного:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

Потім findViewById(R.id.entireLayout).getWidth()поверне ширину екрана і findViewById(R.id.entireLayout).getHeight()поверне висоту екрана.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.