Jak mogę programowo sprawdzić rozmiar ekranu w jednostkach używanych przez zdarzenia dotyku i wyświetlić pomiar / układ? Innymi słowy, chcę mieć współrzędne w prawym dolnym rogu ekranu, w układzie współrzędnych używanym przez zdarzenia dotykowe ”
getRawX()/getRawY()i View.getLocationOnScreen().
Waham się, czy nazywać żądane jednostki zdarzenia / widoku „pikselami”, ponieważ najwyraźniej w moim telefonie jest kilka pojęć „pikseli” w różnych trybach i nie składają się one na spójną historię.
Widzę, że zadawano to wiele pytań i odpowiadano na nie w trybie stackoverflow i gdzie indziej, ale żadna z odpowiedzi nie działa na moim telefonie (droid 4, android 4.1.2) we wszystkich trybach:
- Czy mogę programowo sprawdzić szerokość ekranu w aplikacji na Androida?
- Jak uzyskać programowy rozmiar ekranu w systemie Android
- Android ustawił widoczność widoku programowo na podstawie rozmiaru ekranu
- Jak uzyskać wysokość ekranu w systemie Android?
- Uzyskaj wysokość ekranu w systemie Android
- https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
- http://shuklaxyz.blogspot.com/2012/02/how-to-programmatically-figure-out.html
- http://coderock.net/how-to-determine-screen-resolution-programmatically/
- http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
- Android i programowe ustawianie szerokości i wysokości w jednostkach dp
- http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatically-in-android/
- http://www.androidsnippets.com/get-size-and-orientation-of-the-screen
- http://grokbase.com/t/gg/android-developers/127aatfqb6/how-to-determine-screen-resolution-programmatically
(łał!)
Dotyczy to kodu biblioteki, który musi działać niezależnie od tego, czy aplikacja jest w „trybie zgodności ekranu” (tj. TargetSdkVersion <= 10 w manifeście), czy nie. Nie chcę też robić żadnych założeń dotyczących pozycji, rozmiaru lub istnienie paska stanu lub innych podobnych dekoracji ekranu.
Oto fakty:
mój telefon (droid 4 z systemem Android 4.1.2) ma 540x960 pikseli fizycznych, tj. małe kolorowe, świecące kropki.
rozmiar ekranu w żądanych jednostkach, liczony od zdarzeń dotykowych i pomiarów podglądu, to 360x640, gdy aplikacja jest w trybie zgodności ekranu, 540x960, gdy aplikacja nie jest w trybie zgodności z ekranem. Są to liczby, które muszę znaleźć programowo, bez manipulowania zdarzeniami dotykowymi lub widokami, aby je znaleźć, ale mam ogromne trudności ze znalezieniem jakiegokolwiek interfejsu API, który zwróci te liczby.
Obiekty Display i DisplayMetrics uzyskane na różne sposoby twierdzą, że rozmiar ekranu wynosi 540x960 „pikseli” (niezależnie od tego, czy jest w trybie zgodności z ekranem, czy nie). Mówiąc dokładniej, wszystkie poniższe mówią cały czas 540x960: DisplayMetrics. {Width, height} Pixels, Display.getSize (), Display.getRealSize (), Display.get {Width, Height} (),
Wszystkie obiekty konfiguracyjne uzyskane na różne sposoby mówią screen {Width, Height} Dp = 360x614 (czy to w trybie zgodności ekranu, czy nie). Nie sądzę, żeby to reprezentowało cały ekran, ponieważ proporcje są nieprawidłowe. (Myślę, że to cały ekran bez paska stanu; potrzebuję całego ekranu.) Myślę, że można bezpiecznie powiedzieć, że cały ekran ma 360x640 dp, chociaż nie znam żadnego interfejsu API, który zwraca tę 640.
DisplayMetrics otrzymane na różne sposoby mówią, że „gęstość” wynosi 1,0 f w trybie zgodności ekranu i 1,5 f, gdy nie jest w trybie zgodności ekranu.
Działanie
getWindow().getAttributes().{width,height}nie jest pomocne, ponieważ zazwyczaj zawieraMATCH_PARENTraczej niż rzeczywiste rozmiary. Ale najwyraźniej mogę uzyskać pożądaną odpowiedź z działaniagetWindow().getDecorView().getMeasured{Width,Height}()(co jest w rzeczywistości zaskakujące, ponieważ decorView okna działania nie wygląda tak, jakby zajmował cały ekran; wygląda na to, że zajmuje ekran bez paska stanu). Ale nie chcę na tym polegać, ponieważ jeśli rozmiar okna kiedykolwiek zostanie zmieniony (pojawia się miękka klawiatura? Ktoś wywołuje window.setAttributes ()? Lub może w ogóle nie jestem w działaniu), to najwyraźniej wszystko źle.
Rozumiem, że powinna obowiązywać następująca formuła: piksele = dp * gęstość Wydaje się, że zgadza się ze wszystkimi zgłoszonymi liczbami ((3), (4), (5) powyżej), gdy nie jest w trybie zgodności ekranu: 540x960 = 360x640 * 1,5 Ale w trybie zgodności ekranu nie sumuje się: 540x960! = 360x640 * 1 Coś jest nie tak.
Myślę, że najprostszym wyjaśnieniem jest to, że metody wymienione w (3) powyżej po prostu dają błędną odpowiedź na „piksele” w trybie zgodności z ekranem - to znaczy miały zwracać 360x640 „pikseli”, ale są błędne zamiast tego zwraca 540x960. Ale mogą istnieć inne sposoby spojrzenia na to.
W każdym razie uzyskanie pożądanych liczb, niezależnie od trybu, z powyższych elementów układanki, jest z pewnością trudną łamigłówką. Znalazłem sposób, który wydaje się działać na moim telefonie w obu trybach, ale jest niezwykle okrężny i opiera się na dwóch założeniach, które nadal wydają się dość chwiejne (jak opisano w komentarzach do kodu poniżej).
Oto mój przepis:
/** get screen size in "pixels", i.e. touchevent/view units.
* on my droid 4, this is 360x640 or 540x960
* depending on whether the app is in screen compatibility mode
* (i.e. targetSdkVersion<=10 in the manifest) or not. */
public void getScreenSizePixels(int widthHeightInPixels[/*2*/])
{
Resources resources = getResources();
Configuration config = resources.getConfiguration();
DisplayMetrics dm = resources.getDisplayMetrics();
// Note, screenHeightDp isn't reliable
// (it seems to be too small by the height of the status bar),
// but we assume screenWidthDp is reliable.
// Note also, dm.widthPixels,dm.heightPixels aren't reliably pixels
// (they get confused when in screen compatibility mode, it seems),
// but we assume their ratio is correct.
double screenWidthInPixels = (double)config.screenWidthDp * dm.density;
double screenHeightInPixels = screenWidthInPixels * dm.heightPixels / dm.widthPixels;
widthHeightInPixels[0] = (int)(screenWidthInPixels + .5);
widthHeightInPixels[1] = (int)(screenHeightInPixels + .5);
}
Czy istnieje lepszy / czystszy sposób na znalezienie rozmiaru ekranu?