Wie kann ich meine Bildschirmgröße programmgesteuert in den Einheiten ermitteln, die von Berührungsereignissen verwendet werden, und Messung / Layout anzeigen? Mit anderen Worten, ich möchte die Koordinaten der unteren rechten Ecke des Bildschirms in dem Koordinatensystem, das von Berührungsereignissen
getRawX()/getRawY()und verwendet wird View.getLocationOnScreen().
Ich zögere, die gewünschten Ereignis- / Ansichtseinheiten als "Pixel" zu bezeichnen, da auf meinem Telefon offensichtlich mehrere Begriffe von "Pixeln" in verschiedenen Modi vorhanden sind, die nicht zu einer konsistenten Geschichte führen.
Ich sehe, dass dies im Stackoverflow und anderswo häufig gefragt und beantwortet wurde, aber keine der Antworten funktioniert tatsächlich auf meinem Telefon (Droide 4, Android 4.1.2) in allen Modi:
- Kann ich die Bildschirmbreite programmgesteuert in der Android App ermitteln?
- Wie bekomme ich die ScreenSize programmgesteuert in Android
- Android-Set Sichtbarkeit programmgesteuert basierend auf der Bildschirmgröße anzeigen
- Wie erhalte ich die Höhe des Bildschirms in Android?
- Holen Sie sich die Bildschirmhöhe in Android
- https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
- http://shuklaxyz.blogspot.com/2012/02/how-to-programmatisch-figure-out.html
- http://coderock.net/how-to-determine-screen-resolution-programmatic/
- http://www.codeproject.com/Tips/313848/Get-actual-screen-size-for-the-application-layout
- Android und programmgesteuertes Einstellen von Breite und Höhe in dp-Einheiten
- http://www.simplecodestuffs.com/how-to-get-screen-dimensions-programmatic-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-programmatisch
(Beeindruckend!)
Dies gilt für Bibliothekscode, der unabhängig davon funktionieren muss, ob sich die App im "Bildschirmkompatibilitätsmodus" befindet (dh targetSdkVersion <= 10 im Manifest) oder nicht, und ich möchte auch keine Annahmen über Position und Größe treffen oder das Vorhandensein der Statusleiste oder anderer ähnlicher Bildschirmdekorationen.
Hier sind die Fakten:
Mein Telefon (ein Droide 4 mit Android 4.1.2) hat 540 x 960 physische Pixel, dh kleine farbige leuchtende Punkte.
Die Größe des Bildschirms in den gewünschten Einheiten beträgt 360 x 640, wenn sich die App im Bildschirmkompatibilitätsmodus befindet, 540 x 960, wenn sich die App nicht im Bildschirmkompatibilitätsmodus befindet. Dies sind die Zahlen, die ich programmgesteuert finden muss, ohne mich mit Berührungsereignissen oder Ansichten zu beschäftigen, um sie zu finden, aber ich habe extreme Schwierigkeiten, eine API zu finden, die diese Zahlen zurückgibt.
Alle auf verschiedene Weise erhaltenen Display- und DisplayMetrics-Objekte geben an, dass die Bildschirmgröße 540 x 960 "Pixel" beträgt (unabhängig davon, ob sie im Bildschirmkompatibilitätsmodus vorliegen oder nicht). Um genau zu sein, sagen die folgenden immer 540 x 960: DisplayMetrics. {Breite, Höhe} Pixel, Display.getSize (), Display.getRealSize (), Display.get {Breite, Höhe} (),
Auf verschiedene Weise erhaltene Konfigurationsobjekte sagen alle Bildschirm {Breite, Höhe} Dp = 360x614 (ob im Bildschirmkompatibilitätsmodus oder nicht). Ich glaube nicht, dass dies den gesamten Bildschirm darstellt, da das Seitenverhältnis falsch ist. (Ich denke, es ist der gesamte Bildschirm abzüglich der Statusleiste; ich brauche den gesamten Bildschirm.) Ich kann mit Sicherheit sagen, dass der gesamte Bildschirm 360 x 640 dp groß ist, obwohl ich keine API kenne, die diese 640 zurückgibt.
Auf verschiedene Weise erhaltene DisplayMetrics besagen, dass die "Dichte" im bildschirmkompatiblen Modus 1,0 f und im nicht bildschirmkompatiblen Modus 1,5 f beträgt.
Die Aktivität
getWindow().getAttributes().{width,height}ist nicht hilfreich, da sie normalerweiseMATCH_PARENTeher als tatsächliche Größen enthält. Aber ich kann anscheinend die gewünschte Antwort von einer Aktivität erhaltengetWindow().getDecorView().getMeasured{Width,Height}()(was tatsächlich überraschend ist, da die decorView des Aktivitätsfensters nicht so aussieht, als würde sie den gesamten Bildschirm einnehmen; es sieht so aus, als würde sie den Bildschirm abzüglich der Statusleiste einnehmen). Aber ich möchte mich nicht darauf verlassen, denn wenn die Größe des Fensters jemals geändert wird (eine weiche Tastatur wird angezeigt? Jemand, der window.setAttributes () aufruft? Oder ich bin überhaupt nicht in einer Aktivität), wird dies eindeutig alles sein falsch.
Ich verstehe, dass die folgende Formel gelten soll: Pixel = dp * Dichte Dies scheint mit allen oben angegebenen Zahlen ((3), (4), (5)) übereinzustimmen, wenn Sie sich nicht im Bildschirmkompatibilitätsmodus befinden: 540x960 = 360x640 * 1,5 Im Bildschirmkompatibilitätsmodus summiert sich dies jedoch nicht: 540 x 960! = 360 x 640 * 1 Es stimmt also etwas nicht.
Ich denke, die einfachste Erklärung ist, dass die in (3) oben aufgeführten Methoden im Bildschirmkompatibilitätsmodus einfach die falsche Antwort für "Pixel" geben - das heißt, sie sollten 360 x 640 "Pixel" zurückgeben, aber sie sind falsch stattdessen 540x960 zurückgeben. Es kann aber auch andere Sichtweisen geben.
In jedem Fall ist es sicherlich schwierig, die gewünschten Zahlen unabhängig vom Modus aus den oben genannten Puzzleteilen zu erhalten. Ich habe einen Weg gefunden, der auf meinem Telefon in beiden Modi zu funktionieren scheint, aber er ist äußerst umständlich und basiert auf zwei Annahmen, die immer noch ziemlich wackelig erscheinen (wie in den folgenden Codekommentaren beschrieben).
Hier ist mein Rezept:
/** 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);
}
Gibt es eine bessere / sauberere Möglichkeit, die Größe des Bildschirms zu ermitteln?
DisplayMetricsniemals über solche Änderungen aktualisiert wird. Es gibt Probleme wie diese bereits eingereicht.