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.

Khushboo
quelle

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;
Dax
quelle
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.

serjlee
quelle
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.

Mykhailo Gaidai
quelle
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;
Android-Entwickler
quelle
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;
Supun Madushanka
quelle
8
Erwägen
5

Antwort in Kotlin:

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

Vereinfacht für Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }
TheYogi
quelle
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();
Ali Azaz Alam
quelle
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.

Mathe-Kanal
quelle
0

Versuche dies:

Display display   = getWindowManager().getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int width  = displaySize.x;
int height = displaySize.y;
Muhammed naseef Koppilakkal
quelle
-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);
Dirk le Roux
quelle
3
Diese Antwort ist falsch. Unter developer.android.com/guide/practices/… ist Pixel = Dp * Density.
Vance-Turner