Как определить ширину экрана с точки зрения 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.

Khushboo
источник

Ответы:

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;
Dax
источник
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, это возвращает полезную ширину / высоту экрана (которая должна быть интересной в большинстве случаев). Если вам нужны фактические размеры дисплея, придерживайтесь ответа сверху.

serjlee
источник
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;
разработчик Android
источник
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
    }
Bolling
источник
4

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

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }
TheYogi
источник
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

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

математический канал
источник
0

Попробуй это:

Display display   = getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int width  = displaySize.x;
int height = displaySize.y;
Мухаммед Насиф Коппилаккал
источник
-5

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

Сделай это:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);
Дирк ле Ру
источник
3
Этот ответ неверен. С сайта developer.android.com/guide/practices/… Pixel = Dp * Density.
Вэнс-Тернер