1969 Stimmen

Wie man in Android die Bildschirmabmessungen als Pixel erhält

Ich habe einige benutzerdefinierte Elemente erstellt, die ich programmgesteuert in der oberen rechten Ecke platzieren möchte ( n Pixel vom oberen Rand und m Pixel vom rechten Rand). Daher muss ich die Bildschirmbreite und die Bildschirmhöhe ermitteln und dann die Position festlegen:

int px = screenWidth - m;
int py = screenHeight - n;

Wie erhalte ich screenWidth y screenHeight in der Hauptaktivität?

0 Stimmen

Verwenden Sie dp statt px, da dies Ihr Layout bei anderen Geräten verzerren würde.

0 Stimmen

Vergessen Sie nicht, mit getResources().getDisplayMetrics().density zu multiplizieren, um die Skalierung der Anzeige zu berücksichtigen.

0 Stimmen

Dies beweist, dass die am meisten hochgestufte Antwort nicht immer die beste ist (& viele Leute wiederholen Antworten, um sie zu wiederholen). Anstelle von getSize und der veralteten getWidth/getHeight-Kombination (Fehler ignorieren), versuchen Sie Balaji.K's getMetrics . Der Kommentar von Nik in seiner Antwort erklärt sogar getDisplayMetrics um die Größe der System-/Statusleiste zu berücksichtigen. Sie können auch verwenden Dichte wie jmaculate und LoungeKatt erklärt haben, um die EXAKT Wert: DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels; Getestet in Android v2.2 (API 8) und v4.0 mit guten Ergebnissen und keine Fehler/Warnungen .

3567voto

Josef Pfleger Punkte 73395

Wenn Sie die Anzeigemaße in Pixeln wünschen, können Sie getSize :

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

Wenn Sie sich nicht in einer Activity können Sie den Standard Display über WINDOW_SERVICE :

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

Wenn Sie sich in einem Fragment befinden und dies erreichen möchten, verwenden Sie einfach Activity.WindowManager (in Xamarin.Android) oder getActivity().getWindowManager() (in Java).

Vor getSize eingeführt wurde (in API-Stufe 13), konnten Sie die getWidth y getHeight Methoden, die jetzt veraltet sind:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

Für den von Ihnen beschriebenen Anwendungsfall scheint jedoch ein Rand/Padding im Layout angemessener zu sein.

Eine andere Möglichkeit ist: DisplayMetrics

Eine Struktur, die allgemeine Informationen über eine Anzeige beschreibt, z. B. Größe, Dichte und Skalierung der Schrift. Um auf die DisplayMetrics-Mitglieder zuzugreifen, initialisieren Sie ein Objekt wie folgt:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Wir können verwenden widthPixels um Informationen zu erhalten:

"Die absolute Breite der Anzeige in Pixeln".

Ejemplo:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);

Aktualisierung der API-Stufe 30

final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

0 Stimmen

Kann man das nicht im XML machen?

1 Stimmen

@ Abhishek Susarla: XML-Nutzung ist in der Regel in einer statischen Art und Weise sollten Sie erwarten, dass alles dynamisch durchgeführt werden, hoffen, dass dies hilft Ihnen herauszufinden, ur Problem.

1 Stimmen

Gut erklärt MR Mido. Viele Leute, die neu bei Android sind, verstehen den Zweck der XML-Dateien nicht.

391voto

Balaji.K Punkte 8561

Eine Möglichkeit ist:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Er ist veraltet, und Sie sollten stattdessen den folgenden Code verwenden. Die ersten beiden Zeilen des Codes geben Ihnen die DisplayMetrics Ziele. Diese Objekte enthalten die Felder wie heightPixels , widthPixels .

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;

Api Stufe 30 Update

final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
 // Gets all excluding insets
 final WindowInsets windowInsets = metrics.getWindowInsets();
 Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
         | WindowInsets.Type.displayCutout());

 int insetsWidth = insets.right + insets.left;
 int insetsHeight = insets.top + insets.bottom;

 // Legacy size that Display#getSize reports
 final Rect bounds = metrics.getBounds();
 final Size legacySize = new Size(bounds.width() - insetsWidth,
         bounds.height() - insetsHeight);

19 Stimmen

Beachten Sie, dass sich die Metriken (Breite, Höhe) je nach Drehung des Geräts ändern.

9 Stimmen

Metrics gibt die Größe des Bildschirms an, aber ab HoneyComb hat Ihre Aktivität weniger Platz, als aufgrund der Systemleiste angezeigt wird.

4 Stimmen

@Guy es hängt von Ihrer Implementierung ab. Du kannst die Statusleiste ausblenden: requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

123voto

Es mag Ihre Frage nicht beantworten, aber es könnte nützlich sein, zu wissen (ich habe selbst danach gesucht, als ich zu dieser Frage kam), dass, wenn Sie die Dimension einer Ansicht benötigen, aber Ihr Code ausgeführt wird, wenn das Layout noch nicht festgelegt wurde (zum Beispiel in onCreate() ) können Sie eine ViewTreeObserver.OnGlobalLayoutListener con View.getViewTreeObserver().addOnGlobalLayoutListener() und fügen Sie dort den entsprechenden Code ein, der die Dimension der Ansicht benötigt. Der Callback des Listeners wird aufgerufen, wenn das Layout erstellt wurde.

1 Stimmen

Oder einfach view.post schreiben

1 Stimmen

View.post funktioniert jedoch nicht garantiert. Es ist nur ein Workaround.

1 Stimmen

@marsbear wo steht es View.post() nicht garantiert funktioniert? Ich bin neugierig, weil ich auch auf diese Methode verlassen, um eine Ansicht der Größe nach dem Layout und war nicht bewusst, es unzuverlässig.

111voto

digiphd Punkte 2259

(Antwort von 2012, möglicherweise veraltet) Wenn Sie die Zeit vor Honeycomb unterstützen möchten, müssen Sie eine Abwärtskompatibilität vor API 13 einbauen. Etwas wie:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

Natürlich werden die veralteten Methoden mit der Zeit aus den neuesten SDKs entfernt, aber da wir uns immer noch darauf verlassen, dass die meisten unserer Nutzer Android 2.1, 2.2 und 2.3 haben, ist das, was uns bleibt.

1 Stimmen

Ja, das war im Jahr 2012.

1 Stimmen

Entschuldigung, ich möchte klarstellen, was ich meinte. Es ist höchst unwahrscheinlich, dass jemand API <14 ab 6/22/2015 unterstützen würde

75voto

Dragan Marjanović Punkte 2336

Ich habe alle möglichen "Lösungen" erfolglos ausprobiert und festgestellt, dass die App "Dalvik Explorer" von Elliott Hughes auf allen Android-Geräten/OS-Versionen immer die korrekten Abmessungen anzeigt. Ich landete bei seinem Open-Source-Projekt, das hier gefunden werden kann: https://code.google.com/p/enh/

Hier ist der gesamte relevante Code:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDIT: leicht verbesserte Version (Vermeidung von Ausnahmen bei nicht unterstützten OS-Versionen):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

12 Stimmen

Dies ist der einzige Beitrag hier, der die Fensterdekorationen (Statusleiste/Menüleiste) berücksichtigt. hat für mich gut funktioniert.

6 Stimmen

Toll, aber Sie sollten nie erwartet haben, dass die Geschäftslogik Ausnahmen auslöst. Exception firing (auch wenn gefangen) ist schrecklich für die Leistung. Plus Sie tun mehr Arbeit als nötig, wenn die SDK_INT ist > 13. Stattdessen sollten Sie einfach einige ifs auf die Build.VERSION.SDK_INT.

4 Stimmen

@Erik B, ich stimme zu. Ich habe eine verbesserte Version hinzugefügt. Trotzdem habe ich den Teil "since SDK 1" gelassen, nur für den Fall, dass etwas in try/catch schief geht (ich habe viele schlimme Dinge in Android gesehen, besonders wenn man denkt, dass es unmöglich ist, dass etwas schief geht, also möchte ich es sicher halten :)). Auf jeden Fall sollte es nicht zu viel Overhead geben, da diese Berechnung nur einmal durchgeführt werden sollte (z.B. könnten die Werte in einigen statischen Attributen gehalten werden).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X