Як визначити ширину екрану з точки зору dp чи dip в процесі виконання в Android?


194

Мені потрібно кодувати компонування андроїд-віджетів за допомогою dip / dp (у файлах java). Під час виконання, якщо я кодую

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

це поверне ширину екрана в пікселях (px). Щоб перетворити це в dp, я зашифрував:

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

Це, здається, не відповідає правильній відповіді. Я зробив емулятор WVGA800, роздільна здатність екрана якого становить 480 на 800. Коли запустіть емулятор і дозвольте коду надрукувати значення пікселів і dp, він досяг 320 в обох. Цей емулятор становить 240 dpi, коефіцієнт масштабу якого буде 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;

АБО

Спасибі @ Tomáš Hubálek

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 . Дисплей Дисплей = getWindowManager () getDefaultDisplay (); Розмір точки = нова точка (); display.getSize (розмір); int width = size.x; int висота = size.y;
marienke

1
@dsdsdsdsd: контекст - це будь-який екземпляр класу контексту. Найголовніше, що Activity - це підклас контексту (тому використовуйте це в Activity, а getActivity () у фрагменті). Додаток та сервіс також є підкласами контексту.
Франсуа POYER

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.

Див. Посилання на клас конфігурації

Редагувати: Як зазначає Нік Байкояну, це повертає корисну ширину / висоту екрана (що має бути цікавим у більшості застосувань). Якщо вам потрібні фактичні розміри дисплея, дотримуйтесь верхньої відповіді.


23
Одне важливе відмінність використання екрана Configuration ScreenWidthDp / screenHeightDp проти DisplayMetrics widthPixels / heightPixels - це конфігурація повертає корисні розміри дисплея (мінус рядок стану тощо), тоді як DisplayMetrics повертає розміри на весь екран.
Нік Байкояну

Це лише для API рівня 13 і вище
ono

Щоб додати до коментаря @ NickBaicoianu, і методи getConfiguration (), і getDisplayMetrics () працюють у режимі багато вікон. тобто розміри відображають розмір вікна, а не екрана.
nmw

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

Іншими словами, якщо ви сконструюєте макет шириною, рівній 160dp в портретному режимі, це буде половина екрану на всіх пристроях ldpi / mdpi / hdpi (крім планшетів, я думаю)


На що ви відповіли - це логічне обґрунтування мого запитання. Я це розумію. Як я повинен зашифрувати це в Java, щоб під час виконання, незалежно від роздільної здатності екрана, код підбирав правильну ширину dpi?
Хушбу

Сподіваюся, я цього разу зрозуміла :) Використовуйте DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);в межах діяльності. Потім 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

Відповідь у kotlin:

  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();

Чи повертається це висота і ширина повернення в пікселях або dp?
Таслім Осені

як називається. щільність, тому його дають вам у dp
Алі Азаз Алам

Я не думаю, що
доречно

Сер, це вирішувати вам, чи реалізувати клас, чи безпосередньо кодувати його. З визначеного класу ви можете легко дістати код для прямої реалізації.
Алі Азаз Алам

0

Якщо ви просто хочете дізнатися про ширину екрана, ви можете просто шукати "найменшу ширину екрана" у своїх налаштуваннях для розробників. Можна навіть відредагувати.



-5

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

Зробити це:

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

3
Ця відповідь невірна. Від developer.android.com/guide/practices/… , Pixel = Dp * Щільність.
Vance-Turner
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.