Wie bestimme ich die Bildschirmbreite in dp oder dip zur Laufzeit in Android?


192

Ich muss das Layout der Android-Widgets mit dip / dp (in Java-Dateien) codieren. Zur Laufzeit, wenn ich codiere

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

Dies gibt die Bildschirmbreite in Pixel (px) zurück. Um dies in dp umzuwandeln, habe ich Folgendes codiert:

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

Dies scheint keine korrekte Antwort zu liefern . Ich habe den Emulator von WVGA800 mit einer Bildschirmauflösung von 480 x 800 erstellt. Als der Emulator ausgeführt wurde und der Code die Werte von Pixel und dp drucken ließ, betrug er in beiden Fällen 320. Dieser Emulator hat eine Auflösung von 240 dpi und einen Skalierungsfaktor von 0,75.

Antworten:


376

Versuche dies

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;

ODER

Danke @ Tomáš Hubálek

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

90
Warum muss WindowManager aufgerufen werden? Was ist mit diesem Code? DisplayMetrics displayMetrics = resources.getDisplayMetrics (); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
Tomáš Hubálek

2
Dies funktionierte bei einem Bildschirm mit sehr hoher Dichte nicht. Es war, als hätte es nur einen kleinen Teil des Bildschirms. Diese Lösung hat bei mir funktioniert : stackoverflow.com/a/18712361/956975 Display display = getWindowManager (). GetDefaultDisplay (); Punktgröße = neuer Punkt (); display.getSize (Größe); int width = size.x; int height = size.y;
Marienke

1
@dsdsdsdsd: context ist eine beliebige Instanz der Context-Klasse. Insbesondere ist Aktivität eine Unterklasse des Kontexts (verwenden Sie diese also in einer Aktivität und getActivity () in einem Fragment). Anwendung und Service sind ebenfalls Unterklassen des Kontexts.
François POYER

112

Ich bin auf diese Frage von Google gestoßen und habe später eine einfache Lösung gefunden, die für API> = 13 gültig ist.

Für zukünftige Referenzen:

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.

Siehe Referenz zur Konfigurationsklasse

Bearbeiten: Wie von Nick Baicoianu bemerkt, gibt dies die nutzbare Breite / Höhe des Bildschirms zurück (was bei den meisten Anwendungen interessant sein sollte). Wenn Sie die tatsächlichen Anzeigeabmessungen benötigen, halten Sie sich an die oberste Antwort.


23
Ein wichtiger Unterschied zwischen der Verwendung von screenWidthDp / screenHeightDp von Configuration und DisplayMetrics widthPixels / heightPixels besteht darin, dass Configuration die verwendbaren Anzeigeabmessungen (abzüglich der Statusleiste usw.) zurückgibt, während DisplayMetrics die Vollbildabmessungen zurückgibt.
Nick Baicoianu

Dies ist nur für API Level 13 und
höher

Um den Kommentar von @ NickBaicoianu zu ergänzen, arbeiten sowohl die Methoden getConfiguration () als auch getDisplayMetrics () im Mehrfenstermodus. Das heißt, die Größen entsprechen denen des Fensters, nicht des Bildschirms.
nmw

7

Ihnen fehlt der Standarddichtewert von 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

Mit anderen Worten, wenn Sie Ihr Layout mit einer Breite von 160 dip im Hochformat entwerfen, wird es auf allen ldpi / mdpi / hdpi-Geräten (außer Tablets, glaube ich) die Hälfte des Bildschirms ausmachen.


Was Sie beantwortet haben, ist die logische Begründung für meine Frage. Ich verstehe das. Wie soll ich dies in Java codieren, damit zur Laufzeit unabhängig von der Bildschirmauflösung die richtige dpi-Breite vom Code ausgewählt wird?
Khushboo

Hoffe, ich mache es diesmal richtig :) Verwenden Sie DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);innerhalb der Aktivität. Dann erhalten outMetrics.densitySie den Skalierungsfaktor des aktuellen Geräts, wie in den Dokumenten angegeben
Mykhailo Gaidai

6

Wie wäre es stattdessen damit?

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;


5

Antwort in Kotlin:

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

4

Vereinfacht für Kotlin:

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

2

Holen Sie sich Bildschirmbreite und -höhe in Bezug auf DP mit einer guten Dekoration:

Schritt 1: Schnittstelle erstellen

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

Schritt 2: Implementierungsklasse erstellen

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

Schritt 3: Breite und Höhe der Aktivität ermitteln:

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

Gibt dies Höhe und Breite in Pixel oder dp zurück?
Taslim Oseni

wie .density genannt, deshalb gibt es Ihnen in dp
Ali Azaz Alam

Ich denke nicht, dass es eine gute Idee ist, Ihrer App
Codetöne

Sir, es liegt an Ihnen, ob Sie die Klasse implementieren oder direkt codieren. Aus der definierten Klasse können Sie den Code für die direkte Implementierung einfach extrahieren.
Ali Azaz Alam

0

Wenn Sie nur Ihre Bildschirmbreite wissen möchten, können Sie in Ihren Entwickleroptionen nach "kleinster Bildschirmbreite" suchen. Sie können es sogar bearbeiten.


0

Versuche dies:

Display display   = getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int width  = displaySize.x;
int height = displaySize.y;

-5

Ihr Problem besteht darin, den Float in einen Int zu verwandeln und dabei an Präzision zu verlieren. Sie sollten auch mit dem Faktor multiplizieren und nicht dividieren.

Mach das:

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

3
Diese Antwort ist falsch. Unter developer.android.com/guide/practices/… ist Pixel = Dp * Density.
Vance-Turner
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.