Получить размеры экрана в пикселях

1569

Я создал некоторые пользовательские элементы, и я хочу программно поместить их в верхний правый угол (n пикселей от верхнего края и m пикселей от правого края). Поэтому мне нужно получить ширину экрана и высоту экрана, а затем установить положение:

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

Как мне получить screenWidth и screenHeight в основном мероприятии?

  • 0
    Используйте dp вместо px. потому что это будет искажать ваш макет с другими устройствами ..
  • 0
    Не забудьте умножить на getResources (). GetDisplayMetrics (). Плотность для учета масштабирования экрана
Показать ещё 3 комментария
Теги:
layout
pixel
dimensions
screen

35 ответов

3048
Лучший ответ

Если вы хотите отображать размеры в пикселях, вы можете использовать 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

В случае использования, которое вы описываете, маржа/заполнение в макете представляется более подходящим.

22 октября 2015 года

Другие способы: DisplayMetrics

Структура, описывающая общую информацию о дисплее, такую ​​как размер, плотность и масштабирование шрифтов. Чтобы получить доступ к элементам DisplayMetrics, выполните инициализацию объекта следующим образом:

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

Мы можем использовать widthPixels для получения информации для:

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

Пример:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
  • 0
    Вы не можете сделать это в XML?
Показать ещё 23 комментария
320

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

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;
  • 13
    Обратите внимание, что метрики (ширина, высота) меняются в зависимости от поворота устройства.
  • 8
    Метрики будут возвращать размер дисплея, но HoneyComb и выше, ваша деятельность будет иметь меньше места, чем возвращается из-за системной панели.
Показать ещё 8 комментариев
102

Он может не отвечать на ваш вопрос, но было бы полезно знать (я сам искал его, когда пришел к этому вопросу), что если вам нужно измерение View, но ваш код выполняется, когда его макет не был (например, в onCreate()) вы можете установить ViewTreeObserver.OnGlobalLayoutListener с помощью View.getViewTreeObserver().addOnGlobalLayoutListener() и поместить соответствующий код, для которого требуется измерение вида. Обратный вызов слушателя будет вызываться, когда макет будет выложен.

  • 0
    или просто напишите view.post
  • 2
    суть для быстрой реализации :) gist.github.com/doridori/9208247
Показать ещё 7 комментариев
97

(ответ 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, это то, с чем мы остались.

  • 0
    Да, это было еще в 2012 году.
  • 0
    извините, позвольте мне уточнить, что я имел в виду. Крайне маловероятно, что кто-либо будет поддерживать API <14 по состоянию на 22.06.2015
63

Я пробовал все возможные "решения" безуспешно, и я заметил, что приложение "Dalvik Explorer" Elliott Hughes всегда показывает правильное измерение на любой версии Android/OS. В итоге я посмотрел его проект с открытым исходным кодом, который можно найти здесь: 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) {
}
  • 8
    Это единственный пост, который учитывает оформление окон (строка состояния / строка меню). отлично работал для меня.
  • 4
    Удивительно, однако, вы никогда не должны были ожидать исключений из бизнес-логики. Исключительная стрельба (даже когда поймана) ужасна для производительности. Кроме того, вы выполняете больше работы, чем необходимо, если SDK_INT> 13. Вместо этого вам просто нужно добавить некоторые if в Build.VERSION.SDK_INT.
Показать ещё 5 комментариев
40

Для доступа к высоте строки состояния для устройств Android мы предпочитаем программный способ ее получения:

Пример кода

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

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

Для быстрого доступа

Изображение 2779

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

  • 0
    Как раз то, что мне нужно! getResources().getDisplayMetrics().heightPixels + result дает фактическую полноэкранную высоту. Ответ Драгана Марьяновича также работает, но я предпочитаю это более короткое и простое решение.
  • 0
    Этот подход устарел с Android Marshmallow. Высота строки состояния может меняться от версии устройства или Android. Лучше использовать OnApplyWindowInsetsListener .
39

Простейший способ:

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

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

  • 3
    Это фактически то, как документация говорит вам сделать это ... но это немного бессмысленно, если вы НЕ используете представление. Вы можете использовать что-то еще, например, mglsurfaceview.
  • 2
    это лучше, поскольку родительский вид может не соответствовать размеру дисплея. Но убедитесь, что это сделано в точке, где представление, размер которого вы запрашиваете, уже было размещено, что обычно не будет внутри onCreate (). Вы можете использовать пользовательский обратный вызов из onWindowFocusChanged (boolean hasFocus), который будет вызываться после того, как все виды были измерены и т. Д., Гарантируя, что вы не получите неправильные размеры для интересующего вас вида ...
22

У меня есть две функции: одна для отправки контекста, а другая высота и ширина в пикселях:

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;
}
  • 0
    Вам нужно добавить @SuppressLint("NewApi") чуть выше сигнатуры функции, чтобы иметь возможность компилировать.
  • 0
    Я думаю, что лучше получить высоту и ширину за один раз, а не в отдельных вызовах API, потому что в противном случае они могут быть не синхронизированы. Это может произойти, если ориентация экрана меняется во время работы вашего кода.
16

Разве это не лучшее решение? 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-дюймовом планшете, в зависимости от того, активна ли активность после завершения расчета. Но для моих целей это более чем хорошо. Спасибо!
16

Это код, который я использую для задачи:

// `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();
}

Кажется достаточно чистым и, тем не менее, заботится об устаревании.

16

Для динамического масштабирования с использованием 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>
14

Найдите ширину и высоту экрана:

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

Просто добавив к Франческо ответ. Другой наблюдатель, более подходящий, если вы хотите узнать местоположение в окне или местоположении на экране, ViewTreeObserver.OnPreDrawListener()

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

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

Используя следующий код в Activity.

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

Нужно сказать, что если вы не находитесь в Activity, но в View (или имеете переменную типа View в своей области), нет необходимости использовать WINDOW_SERVICE. Затем вы можете использовать как минимум два способа.

Во-первых:

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

Во-вторых:

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

Все эти методы, которые мы называем здесь, не устарели.

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

Я нашел, что это сделало трюк.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
  • 5
    Круто, но есть одна страшная вещь об этом методе в исходном коде: этот комментарий
8

Это не ответ для OP, так как он хотел отображать размеры в реальных пикселях. Мне нужны размеры в "device-independent-pixels" и собраны ответы отсюда https://stackoverflow.com/questions/4605527/converting-pixels-to-dp и здесь https://stackoverflow.com/questions/6656540/android-convert-px-to-dp-video-aspect-ratio Я придумал это:

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

Я бы обернул код 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;
}
  • 0
    Это происходит сбой на эмуляторе под управлением Android 4.0 (API 14).
7

Существует не устаревший способ сделать это с помощью DisplayMetrics (API 1), что позволяет избежать беспорядка try/catch:

 // 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;
5

Следуйте приведенным ниже методам:

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;
}
  • 0
    mContext.getResources () getDisplayMetrics () widthPixels..; ???
5

Сначала загрузите файл XML, а затем напишите этот код:

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

Покажите ширину и высоту в соответствии с разрешением экрана.

4

Для тех, кто ищет размер экрана без использования Строка состояния и Панель действий (также благодаря ответу 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);
}
4

Если вы не хотите накладных расходов на WindowManagers, Points или Displays, вы можете захватить атрибуты высоты и ширины самого верхнего элемента View в вашем 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() вернет высоту экрана.

  • 2
    нет ... он возвращает 0.
4

Бывают случаи, когда вам нужно знать точные размеры доступного пространства для макета, когда в действии 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();
    }
}    
  • 0
    Очевидно, вы также можете передать высоту в связке.
3

Для получения размеров экрана используйте отображаемые метрики

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

У меня есть активность заставки с LinearLayout как корневое представление, которое имеет match_parent для его ширины и высоты. Это код в методе onCreate() этого действия. Я использую эти меры во всех других действиях приложения.

int displayWidth = getRawDisplayWidthPreHoneycomb();
int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
pf.setScreenParameters(displayWidth, usableDisplayHeight);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
    myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if (left == 0 && top == 0 && right == 0 && bottom == 0) {
                return;
            }
            int displayWidth = Math.min(right, bottom);
            int usableDisplayHeight = Math.max(right, bottom);
            pf.setScreenParameters(displayWidth, usableDisplayHeight);
        }
    });
}

Ниже перечислены реализации описанных выше методов:

private int getRawDisplayWidthPreHoneycomb() {
    WindowManager windowManager = getWindowManager();
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    int widthPixels = displayMetrics.widthPixels;
    int heightPixels = displayMetrics.heightPixels;

    return Math.min(widthPixels, heightPixels);
}

private int getRawDisplayHeightPreHoneycomb() {
    WindowManager w = getWindowManager();
    Display d = w.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    d.getMetrics(metrics);

    int widthPixels = metrics.widthPixels;
    int heightPixels = metrics.heightPixels;

    return Math.max(widthPixels, heightPixels);
}

public int getStatusBarHeight() {
    int statusBarHeight = 0;

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

    return statusBarHeight;
}

Это приводит к росту и ширине используемого дисплея, исключая любые типы баров (строка состояния, панель навигации) для всех версий API и различных типов устройств (телефонов и планшетов).

1

Вы можете получить размер высота, используя:

getResources().getDisplayMetrics().heightPixels;

и размер ширина, используя

getResources().getDisplayMetrics().widthPixels; 
1

Выше ответ не будет работать, если класс Display не будет работать, вы можете получить ширину и высоту ниже.

private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;

    public static int[] getScreenSize(Context context) {
        int[] widthHeight = new int[2];
        widthHeight[WIDTH_INDEX] = 0;
        widthHeight[HEIGHT_INDEX] = 0;

        try {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();

            Point size = new Point();
            display.getSize(size);
            widthHeight[WIDTH_INDEX] = size.x;
            widthHeight[HEIGHT_INDEX] = size.y;

            if (!isScreenSizeRetrieved(widthHeight))
            {
                DisplayMetrics metrics = new DisplayMetrics();
                display.getMetrics(metrics);
                widthHeight[0] = metrics.widthPixels;
                widthHeight[1] = metrics.heightPixels;
            }

            // Last defense. Use deprecated API that was introduced in lower than API 13
            if (!isScreenSizeRetrieved(widthHeight)) {
                widthHeight[0] = display.getWidth(); // deprecated
                widthHeight[1] = display.getHeight(); // deprecated
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return widthHeight;
    }

    private static boolean isScreenSizeRetrieved(int[] widthHeight) {
        return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
    }
1

Простая функция, совместимая с более низкими версиями.

/**
 * @return screen size int[width, height]
 *
 * */
public int[] getScreenSize(){
    Point size = new Point();
    WindowManager w = getWindowManager();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
        w.getDefaultDisplay().getSize(size);
        return new int[]{size.x, size.y};
    }else{
        Display d = w.getDefaultDisplay();
        //noinspection deprecation
        return new int[]{d.getWidth(), d.getHeight()};
    }
}

Использовать:

int width = getScreenSize()[0];
int height = getScreenSize()[1];
0

Вот простая адаптация из некоторых ответов выше в реализации Kotlin. Он требует, как указано выше, windowsSoftInput = "adjustResize" в манифесте:

class KeyboardWatcher(private val layoutRooView: View) {

    companion object {
        private const val MIN_KEYBOARD_HEIGHT = 200f
    }

    private val displayMetrics: DisplayMetrics = layoutRooView.resources.displayMetrics
    private var stateVisible = false

    var observer: ((Boolean) -> Unit)? = null

    init {
        layoutRooView.viewTreeObserver.addOnGlobalLayoutListener {
            val heightDiff = layoutRooView.rootView.height - layoutRooView.height
            if (!stateVisible && heightDiff > dpToPx(MIN_KEYBOARD_HEIGHT)) {
                stateVisible = true
                observer?.invoke(stateVisible)
            } else if(stateVisible) {
                stateVisible = false
                observer?.invoke(stateVisible)
            }
        }
    }

    private fun dpToPx(valueInDp: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, displayMetrics)
    }
}

И использовать:

val activityRootView = findViewById<ViewGroup>(R.id.activityRoot)
KeyboardWatcher(activityRootView).observer = { visible ->
    if (visible) do something here ...
}
0

Эта функция возвращает приблизительный размер экрана в дюймах.

public double getScreenSize()
{
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width=dm.widthPixels;
        int height=dm.heightPixels;
        int dens=dm.densityDpi;
        double wi=(double)width/(double)dens;
        double hi=(double)height/(double)dens;
        double x = Math.pow(wi,2);
        double y = Math.pow(hi,2);
        double screenInches = Math.sqrt(x+y);
        return screenInches;
}
0
DisplayMetrics dm = getResources().getDisplayMetrics();
float fwidth = dm.density * dm.widthPixels;
float fheight = dm.density * dm.heightPixels;

Если getSize получает сообщение об ошибке из-за вашей minSDKVersion, и вы не хотите использовать устаревшие методы (getWidth и getHeight), решение getMetrics было первоначально опубликовано в 2011 году компанией Balaji.K... И Ник добавил комментарий, объясняющий getDisplayMetrics также рассматривает размер строки состояния.

Некоторые другие комментарии относятся к умножению на масштаб (плотность), чтобы получить точное значение поплавка размеров. Протестировано в Android v2.2 (API 8) и v4.0 с хорошими результатами и нет ошибок/предупреждений.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню