Pytanie Uzyskaj wymiary ekranu w pikselach


Stworzyłem kilka niestandardowych elementów i chcę programowo umieścić je w prawym górnym rogu (n piksele od górnej krawędzi i m piksele od prawej krawędzi). Dlatego muszę uzyskać szerokość ekranu i wysokość ekranu, a następnie ustawić pozycję:

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

Jak mogę uzyskać screenWidth i screenHeight w głównej działalności?


1672
2018-06-19 08:25


pochodzenie


Użyj dp zamiast px. ponieważ zakłóci to twój układ z innymi urządzeniami. - Nepster
Nie zapomnij o pomnożeniu przez getResources (). GetDisplayMetrics (). Density aby uwzględnić skalowanie wyświetlacza - jmaculate
To dowodzi, że najczęściej wybierana odpowiedź nie zawsze jest najlepsza (i wiele osób powtórzy odpowiedź dla przedstawiciela). Zamiast getSize i przestarzałej kombinacji getWidth / getHeight (ignorowanie błędów) wypróbuj Balaji.K's getMetrics. Komentarz Nik w swojej odpowiedzi nawet wyjaśnia getDisplayMetrics do rozważenia rozmiaru systemu / paska stanu. Możesz również użyć gęstość jako jmaculate i LoungeKatt wyjaśnił, że ma DOKŁADNY wartość:DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels; Testowane w systemie Android w wersji 2.2 (API 8) i wersji 4.0 z dobrymi wynikami i brak błędów / ostrzeżeń. - Armfoot
DisplayMetrics displaymetrics = new DisplayMetrics (); getWindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; - Azahar


Odpowiedzi:


Jeśli chcesz mieć wymiary wyświetlania w pikselach, które możesz wykorzystać getSize:

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

Jeśli nie jesteś w Activity możesz uzyskać domyślną Display przez WINDOW_SERVICE:

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

Przed getSize został wprowadzony (na poziomie API 13), możesz użyć getWidth i getHeight metody, które są teraz przestarzałe:

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

Jednak w przypadku użycia, które opisujesz, margines / dopełnienie w układzie wydaje się bardziej odpowiednie.

Inny sposób to: DisplayMetrics

Struktura opisująca ogólne informacje o wyświetlaczu, takie jak jego rozmiar, gęstość i skalowanie czcionek. Aby uzyskać dostęp do członków DisplayMetrics, zainicjuj taki obiekt:

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

Możemy użyć widthPixels uzyskać informacje dla:

"Bezwzględna szerokość ekranu w pikselach."

Przykład:

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

3328
2018-06-19 08:41



developer.android.com/reference/android/view/Display.html - gcb
getWidth () lub getSize ()? Co powinienem użyć, jeśli chcę, aby moja aplikacja działała na API <13, a także API> 13? - Carol
spróbuj {display.getSize (rozmiar); width = size.x; height = size.y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); } - Arnaud
Nie rozumiem, dlaczego chcesz skorzystać try/catch za taki czek? Dlaczego po prostu nie skorzystać if (android.os.Build.VERSION.SDK_INT >= 13) bez żadnego odrzuconego wyjątku? Myślę o try/catch w normalnym działaniu aplikacji jako zła praktyka. - CipherCom
co jeśli chcesz uzyskać rozmiar ekranu z wyłączeniem paska nawigacyjnego i / lub paska powiadomień - android developer


Jednym ze sposobów jest:

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

Jest przestarzałe i powinieneś wypróbować poniższy kod. Pierwsze dwa wiersze kodu dają objekty DisplayMetrics. Ten obiekt zawiera pola takie jak heightPixels, widthPixels.

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

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

350
2018-01-31 02:01



Zwróć uwagę, że metryki (szerokość, wysokość) zmieniają się w zależności od rotacji urządzenia. - Tony Chan
Metryki zwrócą rozmiar ekranu, ale HoneyComb i wyżej, twoja aktywność będzie miała mniej miejsca niż to, co jest zwracane z powodu paska systemu. - Guy
@Guy to zależy od twojej implementacji. Możesz ukryć pasek stanu: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - Hagai L
Istnieje również w ten sposób: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels - Nik
końcowa zmienna zmienna = getResources (). getDisplayMetrics (). density; int width = (int) (metry.widthPixels * scale + 0.5f); - Musisz uwzględnić gęstość urządzeń, kiedy robisz to w ten sposób. - Abandoned Cart


Może nie odpowiedzieć na twoje pytanie, ale może być przydatne wiedzieć (szukałem tego sam, gdy doszłam do tego pytania), że jeśli potrzebujesz wymiaru widoku, ale twój kod jest wykonywany, gdy jego układ nie został jeszcze opracowany (na przykład w onCreate() ) możesz ustawić a ViewTreeObserver.OnGlobalLayoutListener z View.getViewTreeObserver().addOnGlobalLayoutListener() i wstaw odpowiedni kod, który wymaga wymiaru widoku. Oddzwanianie odbiorcy zostanie wywołane, gdy układ zostanie ułożony.


111
2018-04-06 21:23



lub po prostu napisz view.post - Lukas Hanacek
Istota dla szybkiej realizacji :) gist.github.com/doridori/9208247 - Dori
view.post nie może jednak działać. To tylko obejście. - marsbear
@marsbear, gdzie to mówi View.post() nie ma gwarancji działania? Jestem ciekawy, ponieważ polegam również na tej metodzie, aby uzyskać rozmiar widoku po ułożeniu i nie zdawałem sobie sprawy, że to niewiarygodne. - Tony Chan
@Turbo Powiedziałem: p Użyliśmy tego obejścia przedtem i okazało się, że nie jesteśmy wiarygodni. To obejście opiera się na założeniu, że początkowe układanie odbywa się w tym samym obrocie UIThread jako inicjalizacji. W związku z tym można zaplanować uruchomienie kodu przed następnym przejściem przez UI post () i dobrze. Okazało się, że układ może potrwać nawet dłużej w pewnych okolicznościach, a widok nadal nie był układany, gdy działał opublikowany kod. Teraz mogę dodać ViewTreeObserver w onCreate i usunąć go po pierwszym uruchomieniu onLayout. Rozpocznij swoje rzeczy podczas pierwszego offLayout. - marsbear


(2012 odpowiedź, może być nieaktualne) Jeśli chcesz wspierać pre Honeycomb, będziesz musiał wprowadzić wsteczną kompatybilność przed API 13. Coś jak:

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

Oczywiście wycofane metody zostaną ostatecznie usunięte z najnowszych pakietów SDK, ale mimo że nadal polegamy na większości naszych użytkowników posiadających Androida 2.1, 2.2 i 2.3, to jest to, co nam pozostaje.


103
2017-07-24 03:14



Tak, to było w 2012 roku. - digiphd
przepraszam, pozwól mi wyjaśnić, o co mi chodzi. Jest mało prawdopodobne, aby ktokolwiek wspierał interfejs API <14 od 22.02.2015 - sudocoder


Wypróbowałem wszystkie możliwe "rozwiązania" bez powodzenia i zauważyłem, że aplikacja "Dalvik Explorer" Elliotta Hughesa zawsze pokazuje poprawny wymiar w dowolnej wersji urządzenia / systemu operacyjnego Android. Skończyło się na tym, że patrzę na jego projekt open source, który można znaleźć tutaj: https://code.google.com/p/enh/

Oto cały odpowiedni kod:

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

EDYCJA: nieznacznie ulepszona wersja (unikaj wyjątków podczas wypalania w nieobsługiwanej wersji systemu operacyjnego):

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

62
2018-03-29 08:15



Jest to jedyny post, który bierze pod uwagę dekoracje okien (pasek stanu / pasek menu). pracował dla mnie świetnie. - Andy Cochrane
Niesamowite, ale nigdy nie powinieneś oczekiwać wyjątków od logiki biznesowej. Strzelanie z wyjątków (nawet po złapaniu) jest okropne dla wydajności. Plus robisz więcej pracy niż potrzeba, jeśli SDK_INT jest> 13. Zamiast tego powinieneś po prostu dodać kilka ifs na Build.VERSION.SDK_INT. - Erik B
@Erik B, zgadzam się. Dodałem ulepszoną wersję. Nadal opuściłem część "od SDK 1", na wypadek, gdyby coś poszło nie tak w Try / catch (widziałem wiele złych rzeczy w Androidzie, zwłaszcza, gdy wydaje ci się, że coś jest nie tak, więc lubię to bezpieczne :)) . W każdym razie nie powinno być zbyt wiele uwagi, ponieważ obliczenia należy wykonywać tylko raz (np. Wartości można zachować w niektórych statycznych atrybutach). - Dragan Marjanović
Zauważ, że ten kod jest licencjonowany na licencji GPL v3, co ma wpływ na używanie go w aplikacjach produkcyjnych. - TalkLittle
GPL i w zależności od refleksji metody wywoływania, które mogą nie być obecne w przyszłych wersjach Androida. Mhhh - Michel


Aby uzyskać dostęp do wysokości paska stanu dla urządzeń z systemem Android, preferujemy programowy sposób, aby go uzyskać:

Przykładowy kod

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

Zmienna result podaje wysokość w pikselu.

Dla szybkiego dostępu

Enter image description here

Aby uzyskać więcej informacji o wysokości Title bar, Navigation bar i Content View, życzliwie popatrz Rozmiary ekranu urządzenia Android.


43
2017-08-27 13:12



Dokładnie to, czego potrzebowałem! getResources().getDisplayMetrics().heightPixels + result daje rzeczywistą pełną wysokość ekranu. Odpowiedź Dragana Marjanovicia również działa, ale ja wolę to znacznie krótsze i prostsze rozwiązanie. - Michel
To podejście jest nieaktualne od Androida Marshmallow. Wysokość paska stanu może się zmieniać w zależności od urządzenia lub wersji Androida. Lepsze wykorzystanie OnApplyWindowInsetsListener. - Heinrich


Najprostszy sposób:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

42
2017-11-26 10:47



Również jedyne z tych rozwiązań, które sprawdziły się u mnie - ShadowGod
to jest sposób. (Y) - Ahsan Sher
Prosta funkcja do robienia tego samego .. Zobacz ten post whats-online.info/science-and-tutorials/121/... - Daniel Nyamasyo


Najpierw zdobądź widok (np findViewById()), a następnie możesz użyć getWidth () na samym widoku.


28
2018-06-19 08:38



Tak właśnie jest w dokumentacji mówiącej o tym ... ale nie ma sensu, jeśli NIE korzystasz z widoku. możesz użyć czegoś innego, np. mglsurfaceview. - gcb
jest to lepsze, ponieważ widok nadrzędny może nie być wielkości wyświetlacza. Ale upewnij się, że jest to zrobione w punkcie, w którym widok, którego dotyczy kwerenda, został już wyodrębniony, co zwykle nie występuje w funkcji onCreate (). Możesz użyć niestandardowego wywołania zwrotnego z onWindowFocusChanged (boolean hasFocus), które będzie wywoływane po zmierzeniu wszystkich widoków i tak dalej, zapewniając, że nie otrzymasz niepoprawnych wymiarów dla widoku, który Cię interesuje ... - Dori