Как определить ширину экрана с точки зрения dp или dip во время выполнения в Android?


194

Мне нужно кодировать макет виджетов Android с помощью DIP / DP (в файлах Java). Во время выполнения , если я код,

int pixel=this.getWindowManager().getDefaultDisplay().getWidth();

это возвращает ширину экрана в пикселях (px). Чтобы преобразовать это в dp, я закодировал:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

это, кажется, не возвращает правильный ответ. Я сделал эмулятор WVGA800 с разрешением экрана 480 на 800. Когда запустил эмулятор и позволил коду напечатать значения pixel и dp, он достиг 320 в обоих. Этот эмулятор имеет 240 точек на дюйм, масштабный коэффициент которого будет 0,75.

Ответы:


378

Попробуй это

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

ИЛИ

Спасибо @ Томаш Хубалек

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

91
Почему нужно вызывать WindowManager? Как насчет этого кода? DisplayMetrics displayMetrics = resources.getDisplayMetrics (); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
— Томаш Губалек

2
Это не сработало для меня при использовании экрана с очень высокой плотностью. Как будто он получил только небольшую часть экрана. Это решение сработало для меня: stackoverflow.com/a/18712361/956975 Display display = getWindowManager (). GetDefaultDisplay (); Размер точки = новая точка (); display.getSize (размер); int width = size.x; int height = size.y;
— Мариенке

1
@dsdsdsdsd: context - это любой экземпляр класса Context. В частности, Activity является подклассом Context (поэтому используйте его в Activity, а getActivity () - во фрагменте). Приложение и Сервис также являются подклассами Context.
— Франсуа Пуае

112

Я наткнулся на этот вопрос от Google, а позже я нашел простое решение для API> = 13.

Для будущих ссылок:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

См. Ссылку на класс конфигурации

Редактировать: Как отметил Ник Baicoianu, это возвращает полезную ширину / высоту экрана (которая должна быть интересной в большинстве случаев). Если вам нужны фактические размеры дисплея, придерживайтесь ответа сверху.


23
Одним из важных различий между использованием параметров screenWidthDp / screenHeightDp и DisplayMetrics widthPixels / heightPixels является то, что конфигурация возвращает используемые размеры дисплея (за исключением строки состояния и т. Д.), Тогда как DisplayMetrics возвращает полноэкранные размеры.
— Ник Baicoianu

Это только для API уровня 13 и выше
— ono

Чтобы добавить комментарий @ NickBaicoianu, оба метода getConfiguration () и getDisplayMetrics () работают в многооконном режиме. то есть размеры отражают размер окна, а не экрана.
— МЗП

7

Вам не хватает значения плотности по умолчанию 160.

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

Другими словами, если вы создадите макет с шириной, равной 160 dip, в портретном режиме, он будет составлять половину экрана на всех устройствах ldpi / mdpi / hdpi (кроме планшетов, я думаю)


То, что вы ответили, является логическим обоснованием моего вопроса. Я это поняла. Как я должен кодировать это в Java, чтобы во время выполнения независимо от разрешения экрана код выбирал правильную ширину точек на дюйм?
— Khushboo

Надеюсь, я правильно понял на этот раз :) Используйте DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);в Activity. Затем, outMetrics.densityдаст вам масштабный коэффициент текущего устройства, как указано в документации
— Михаил Гайдай

6

Как насчет использования этого вместо?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;

6
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;

8
Подумайте над объяснением
— bigbounty

5

Ответ в котлине:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }

4

Упрощенно для Котлина:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }

2

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

Шаг 1: Создать интерфейс

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

Шаг 2: Создать класс реализатора

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

Шаг 3: Получить ширину и высоту в деятельности:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();

Это возвращает высоту и ширину в пикселях или дп?
— Таслит Осень

как называется .density, поэтому его дают вам в дп
— Али Азаз Алам

Я не думаю, что было бы хорошей идеей добавить тоны кода в ваше приложение для решения простой задачи
— Руслан Берозов

Сэр, вам решать, реализовывать ли класс или напрямую его кодировать. Из определенного класса вы можете легко извлечь код для непосредственной реализации.
— Али Азаз Алам

0

Если вы просто хотите узнать ширину вашего экрана, вы можете просто найти «наименьшую ширину экрана» в опциях разработчика. Вы даже можете редактировать это.



-5

Ваша проблема с приведением числа с плавающей точкой к int, теряющим точность. Вы должны также умножить на коэффициент и не делить.

Сделай это:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);

3
Этот ответ неверен. С сайта developer.android.com/guide/practices/… Pixel = Dp * Density.
— Вэнс-Тернер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.