Jak uzyskać wymiary ekranu jako piksele w Androidzie

1842

Utworzyłem niektóre niestandardowe elementy i chcę programowo umieścić je w prawym górnym rogu ( npiksele od górnej krawędzi i mpiksele od prawej krawędzi). Dlatego muszę uzyskać szerokość i wysokość ekranu, a następnie ustawić pozycję:

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

W jaki sposób uzyskać screenWidthi screenHeightw głównej działalności?

Niko Gamulin
źródło
Użyj dp zamiast px. ponieważ to zniekształci twój układ z innymi urządzeniami ..
Jawad Zeb
Nie zapomnij pomnożyć przez getResources (). GetDisplayMetrics (). Gęstość, aby uwzględnić skalowanie wyświetlania
jmaculate
To dowodzi, że najlepiej głosowana odpowiedź nie zawsze jest najlepsza (i wiele osób powtarza odpowiedzi w celu powtórzenia). Zamiast getSize i przestarzałej kombinacji getWidth / getHeight (ignorowanie błędów), wypróbuj Balaji.K's getMetrics. Komentarz Nik w jego odpowiedzi wyjaśnia nawet, że getDisplayMetricsnależy wziąć pod uwagę rozmiar systemu / paska stanu. Możesz także użyć gęstości jako jmaculate, a LoungeKatt wyjaśnił, że ma wartość DOKŁADNĄ : DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;Przetestowano w systemie Android v2.2 (API 8) i v4.0 z dobrymi wynikami i bez błędów / ostrzeżeń .
Armfoot
DisplayMetrics displaymetrics = new DisplayMetrics (); getWindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels;
Azahar
Innym sposobem, aby uzyskać DisplayMetrics: Resources.getSystem().getDisplayMetrics(). Nie będziesz musiał Contextich zdobyć.
Täg

Odpowiedzi:

3478

Jeśli chcesz wymiary wyświetlania w pikselach, możesz użyć getSize:

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

Jeśli nie ma Cię w domu Activity, możesz uzyskać ustawienia domyślne Displaypoprzez WINDOW_SERVICE:

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

Jeśli jesteś we fragmencie i chcesz to osiągnąć, po prostu użyj Activity.WindowManager (w Xamarin.Android) lub getActivity (). GetWindowManager () (w java).

Przed getSizewprowadzeniem (na poziomie API 13) można było użyć metod getWidthi getHeight, które są teraz przestarzałe:

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

Jednak w opisywanym przypadku użycia margines / wypełnienie układu wydaje się bardziej odpowiednie.

Innym sposobem jest: DisplayMetrics

Struktura opisująca ogólne informacje o ekranie, takie jak jego rozmiar, gęstość i skalowanie czcionek. Aby uzyskać dostęp do elementów DisplayMetrics, zainicjuj obiekt w następujący sposób:

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

Możemy użyć, widthPixelsaby uzyskać informacje na temat:

„Bezwzględna szerokość wyświetlacza w pikselach”.

Przykład:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);
Josef Pfleger
źródło
13
getWidth () czy getSize ()? Z czego skorzystałbym, gdyby moja aplikacja działała na API <13 oraz API> 13?
Carol
52
spróbuj {display.getSize (rozmiar); szerokość = rozmiar. x; wysokość = rozmiar. y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); }
Arnaud
248
Nie rozumiem, dlaczego chcesz skorzystać try/catchz takiej kontroli? Dlaczego po prostu nie użyć if (android.os.Build.VERSION.SDK_INT >= 13)żadnego wyjątku? W try/catchnormalnym przepływie aplikacji myślę, że to zła praktyka.
Patrik
2
@ A-Live wtedy aplikacja również się zepsuje (ale się nie zawiesi). My, programiści, musimy jednak wstępnie sprawdzić nową wersję systemu operacyjnego i może to po prostu ukryć problem. Również z tym argumentem można / należy otoczyć co kilka linii kodu metodą try / catch, co moim zdaniem jest złą praktyką, jak już wspomniano.
Patrik,
11
co jeśli chcesz uzyskać rozmiar ekranu z wyjątkiem paska nawigacji i / lub paska powiadomień
programista Androida
374

Jednym ze sposobów jest:

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

Jest przestarzały i powinieneś zamiast tego wypróbować następujący kod. Pierwsze dwa wiersze kodu zawierają DisplayMetricsobjecs. Te obiekty znajdują się pola, na przykład heightPixels, widthPixels.

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

int height = metrics.heightPixels;
int width = metrics.widthPixels;
Balaji.K
źródło
14
Pamiętaj, że dane (szerokość, wysokość) zmieniają się w zależności od obrotu urządzenia.
Tony Chan
8
Metryki zwrócą rozmiar ekranu, ale HoneyComb i więcej, twoja aktywność będzie miała mniej miejsca niż to, co zostało zwrócone z powodu paska systemowego.
Guy
3
@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
79
Istnieje również w ten sposób: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels
Nik
final float scale = getResources (). getDisplayMetrics (). gęstość; int width = (int) (metrics.widthPixels * skala + 0,5f); - Robiąc to w ten sposób, musisz uwzględnić gęstość urządzeń.
Opuszczony
119

Może nie odpowiedzieć na twoje pytanie, ale warto wiedzieć (szukałem go sam, kiedy przyszedłem do tego pytania), że jeśli potrzebujesz wymiaru Widoku, ale kod jest wykonywany, gdy jego układ nie został jeszcze ułożony (na przykład w onCreate()) możesz ustawić za ViewTreeObserver.OnGlobalLayoutListenerpomocą View.getViewTreeObserver().addOnGlobalLayoutListener()i wstawić odpowiedni kod, który potrzebuje wymiaru widoku. Oddzwonienie nasłuchiwania zostanie wywołane, gdy układ zostanie ułożony.

Francesco Feltrinelli
źródło
lub po prostu napisz view.post
Lukas Hanacek,
Nie gwarantuje się jednak działania view.post. To tylko obejście.
marsbear
@marsbear, gdzie jest napisane, że View.post()nie gwarantuje się, że zadziała? Jestem ciekawy, ponieważ polegam również na tej metodzie uzyskania rozmiaru Widoku po układzie i nie wiedziałem, że to niewiarygodne.
Tony Chan
@Turbo Mówię to: p Użyliśmy tego obejścia wcześniej i okazało się to niewiarygodne. To obejście opiera się na założeniu, że początkowe układanie odbywa się w tym samym cyklu UIThread co inicjalizacja. Dlatego możesz zaplanować uruchomienie kodu przed kolejną zmianą interfejsu użytkownika za pomocą post () i wszystko będzie w porządku. Okazało się, że układ w niektórych okolicznościach może potrwać dłużej, a widok nadal nie był układany, gdy działał opublikowany kod. To, co teraz robię, to dodaj ViewTreeObserver w onCreate i usuń go po pierwszym onLayout. Zainicjuj swoje rzeczy podczas pierwszego układu.
marsbear
@marsbear czy to ma znaczenie, z którego Viewmasz ViewTreeObserver? A może wszystkie mają ten sam?
Tony Chan,
109

(Odpowiedź z 2012 r. Może być nieaktualna) Jeśli chcesz obsługiwać wersję wcześniejszą o strukturze plastra miodu, musisz wprowadzić wsteczną zgodność przed API 13. Coś takiego:

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 przestarzałe metody zostaną w końcu usunięte z najnowszych zestawów SDK, ale chociaż nadal polegamy na większości naszych użytkowników posiadających Androida 2.1, 2.2 i 2.3, pozostaje nam to.

digiphd
źródło
Tak, to było w 2012 roku.
digiphd
przepraszam, pozwól mi wyjaśnić, co miałem na myśli. Jest bardzo mało prawdopodobne, aby ktokolwiek obsługiwał API <14 na dzień
22.06.2015
69

Bezskutecznie wypróbowałem wszystkie możliwe „rozwiązania” i zauważyłem, że aplikacja „Dalvik Explorer” Elliotta Hughesa zawsze pokazuje prawidłowy wymiar na dowolnej wersji urządzenia / systemu Android. Skończyło się na jego projekcie 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: nieco ulepszona wersja (unikaj wyzwalania wyjątków 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) {
}
Dragan Marjanović
źródło
9
To jedyny post, który uwzględnia dekoracje okien (pasek stanu / pasek menu). działało świetnie dla mnie.
Andy Cochrane
5
Niesamowite, jednak nigdy nie powinieneś oczekiwać wyjątków od logiki biznesowej. Wystrzelenie wyjątku (nawet gdy zostanie złapany) jest straszne dla wydajności. Dodatkowo wykonujesz więcej pracy, niż jest to potrzebne, jeśli SDK_INT ma> 13. Zamiast tego powinieneś po prostu dodać ifs w Build.VERSION.SDK_INT.
Erik B,
3
@Erik B, zgadzam się. Dodałem ulepszoną wersję. Nadal jednak zostawiłem część „od SDK 1” na wypadek, gdyby coś poszło nie tak podczas try / catch (widziałem wiele złych rzeczy w Androidzie, szczególnie gdy uważasz, że coś jest nie tak, więc lubię to chronić :)) . W każdym razie nie powinno być zbyt dużego obciążenia, ponieważ obliczenia należy wykonać tylko raz (np. Wartości mogą być przechowywane w niektórych atrybutach statycznych).
Dragan Marjanović
8
Pamiętaj, że ten kod jest licencjonowany na licencji GPL v3, co ma wpływ na korzystanie z aplikacji produkcyjnych.
TalkLittle
GPL i w zależności od refleksji nad metodami wywoływania, które mogą nie być obecne w przyszłych wersjach Androida. Mhhh
Michel
47

Najprostszy sposób:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 
Zelleriation
źródło
46

Aby uzyskać dostęp do wysokości paska stanu dla urządzeń z Androidem, preferujemy programowy sposób jej uzyskania:

Przykładowy kod

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

Zmienna resultpodaje wysokość w pikselu.

Szybki dostęp

Wpisz opis zdjęcia tutaj

Aby uzyskać więcej informacji na temat wysokości Title bar, Navigation bari Content View, uprzejmie wygląd na ekranie Android Device rozmiarach .

Sonar Swapnil
źródło
Dokładnie to, czego potrzebowałem! getResources().getDisplayMetrics().heightPixels + resultdaje rzeczywistą wysokość pełnego ekranu. Odpowiedź Dragana Marjanovicia również działa, ale wolę to znacznie krótsze i prostsze rozwiązanie.
Michel
To podejście jest przestarzałe od Androida Marshmallow. Wysokość paska stanu można zmienić w zależności od wersji urządzenia lub systemu Android. Lepsze wykorzystanie OnApplyWindowInsetsListener.
Heinrich
32

Najpierw pobierz widok (np. Przez findViewById()), a następnie możesz użyć getWidth () na samym widoku.

Marcin Gil
źródło
3
W rzeczywistości tak mówi dokumentacja, ale nie ma sensu, jeśli NIE używasz widoku. możesz używać czegoś innego, np. mglsurfaceview.
gcb
2
jest to lepsze, ponieważ widok nadrzędny może nie mieć wielkości wyświetlacza. Ale upewnij się, że jest to zrobione w punkcie, w którym widok, o który pytasz, ma już rozmiar, który zwykle nie jest w onCreate (). Możesz użyć niestandardowego wywołania zwrotnego z onWindowFocusChanged (boolean hasFocus), który zostanie wywołany po zmierzeniu wszystkich widoków itd., Zapewniając, że nie otrzymasz niepoprawnych wymiarów dla widoku, który Cię interesuje ...
Dori
27

Mam dwie funkcje, jedną do wysyłania kontekstu, a drugą do uzyskiwania wysokości i szerokości w pikselach:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

i

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}
Jorgesys
źródło
Musisz dodać @SuppressLint("NewApi")tuż powyżej podpisu funkcji, aby móc skompilować.
Adil Malik
Myślę, że lepiej jest uzyskać wysokość i szerokość za jednym razem niż w osobnych wywołaniach interfejsów API, ponieważ w przeciwnym razie mogłyby one nie być zsynchronizowane. Może się to zdarzyć, jeśli orientacja ekranu zmienia się podczas działania kodu.
Sam
17

Do dynamicznego skalowania za pomocą XML istnieje atrybut o nazwie „android: layout_weight”

Poniższy przykład, zmodyfikowany na podstawie odpowiedzi synic na ten wątek , pokazuje przycisk, który zajmuje 75% ekranu (waga = 0,25) oraz widok tekstowy zajmujący pozostałe 25% ekranu (waga = 0,75).

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>
Crbreingan
źródło
17

Oto kod, którego używam do zadania:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

Wydaje się wystarczająco czysty, a jednak zajmuje się deprecjacją.

Pijusn
źródło
17

Czy to nie jest o wiele lepsze rozwiązanie? DisplayMetrics zawiera wszystko, czego potrzebujesz i działa z API 1.

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

Możesz także uzyskać rzeczywisty obraz (w tym dekory ekranu, takie jak pasek stanu lub pasek nawigacji oprogramowania) za pomocą getRealMetrics , ale działa to tylko w przypadku 17+.

Czy coś brakuje?

David Corsalini
źródło
1
Nie odejmuje miejsca na kontrolki ekranowe (takie jak tablety lub urządzenia Nexus). Otrzymuję także inną wartość (750 vs 800) na moim 10-calowym tablecie, w zależności od tego, czy aktywność jest aktywna po zakończeniu obliczeń. Ale dla moich celów jest to więcej niż w porządku. Dziękuję!
Steven L
15

Właśnie dodając do odpowiedzi Francesco. Innym obserwatorem, który jest bardziej odpowiedni, jeśli chcesz dowiedzieć się o lokalizacji w oknie lub lokalizacji na ekranie, jest ViewTreeObserver.OnPreDrawListener ()

Można to również wykorzystać do znalezienia innych atrybutów widoku, które są w większości nieznane w czasie onCreate (), np. Pozycja przewijana, pozycja skalowana.

pellucide
źródło
15

Używanie następującego kodu w działaniu.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;
Vinothkumar Arputharaj
źródło
15

Znajdź szerokość i wysokość ekranu:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Korzystając z tego, możemy uzyskać najnowszy i wyższy zestaw SDK 13.

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}
NagarjunaReddy
źródło
15
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;
Cristiana Chavez
źródło
12

Uważam, że to załatwiło sprawę.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);
Justin
źródło
5
Schłodzić ale jest jeden straszny rzeczą w tej metodzie w źródłowego: Ten komentarz
Norbert
12

Trzeba powiedzieć, że jeśli nie jesteś w Activity, ale Viewmasz (lub masz zmienną Viewtypu w swoim zakresie), nie musisz tego używać WINDOW_SERVICE. Następnie możesz użyć co najmniej dwóch sposobów.

Pierwszy:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

Druga:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

Wszystkie te metody, które tu nazywamy, nie są przestarzałe.

Siergiej Pikalev
źródło
12
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}
Shoaib Ahmed
źródło
11

Aby uzyskać wymiary ekranu, użyj mierników wyświetlacza

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

Uzyskaj wysokość i szerokość w pikselach

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;
Sharath Kumar
źródło
9

To nie jest odpowiedź dla OP, ponieważ chciał wymiary wyświetlacza w rzeczywistych pikselach. Chciałem wymiary w „niezależny od urządzenia-pikseli” i umieszczenie odpowiedzi razem stąd https://stackoverflow.com/a/17880012/253938 i tutaj https://stackoverflow.com/a/6656774/253938 wymyśliłem z tym:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);
RenniePet
źródło
9

Możesz uzyskać wysokość, używając:

getResources().getDisplayMetrics().heightPixels;

i szerokość za pomocą

getResources().getDisplayMetrics().widthPixels; 
Jéwôm ”
źródło
8

Istnieje nieaktualny sposób na wykonanie tego za pomocą DisplayMetrics (API 1), który pozwala uniknąć bałaganu try / catch:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;
paulrehkugler
źródło
8

Owinąłbym kod getSize w ten sposób:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}
Szymon
źródło
Awaria w emulatorze z systemem Android 4.0 (API 14).
jww
6

Dla kogo szuka użytkowej wymiaru ekranu bez paska stanu i działania Bar (także dzięki za odpowiedź Swapnil):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

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

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}
Francesco Vadicamo
źródło
6

Najpierw załaduj plik XML, a następnie napisz ten kod:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

Pokaż szerokość i wysokość zgodnie z rozdzielczością ekranu.

duggu
źródło
6

Postępuj zgodnie z poniższymi metodami:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}
sonida
źródło
6

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}
Khemraj
źródło
5

Są chwile, kiedy trzeba znać dokładne wymiary dostępnej przestrzeni dla układu, gdy jest onCreate działania. Po namyśle opracowałem ten sposób.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

Jeśli z jakiegoś powodu nie chcesz dodać innej aktywności do manifestu Androida, możesz to zrobić w ten sposób:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    
Steve Waring
źródło
Oczywiście można również cofnąć wysokość w pakiecie.
Steve Waring
5

Jeśli nie chcesz nakładać się na menedżery okien, punkty lub wyświetlacze, możesz pobrać atrybuty wysokości i szerokości najwyższego elementu widoku w pliku XML, pod warunkiem, że jego wysokość i szerokość są ustawione na match_parent. (Dzieje się tak, o ile układ zajmuje cały ekran).

Na przykład, jeśli twój XML zaczyna się od czegoś takiego:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

Następnie findViewById(R.id.entireLayout).getWidth()zwróci szerokość ekranu i findViewById(R.id.entireLayout).getHeight()zwróci wysokość ekranu.

Christinac
źródło