Come posso scoprire la mia dimensione dello schermo a livello di codice, nelle unità utilizzate dagli eventi touch e Visualizza misurazione / layout? In altre parole, voglio le coordinate dell'angolo in basso a destra dello schermo, nel sistema di coordinate utilizzato dagli eventi touch '
getRawX()/getRawY()e View.getLocationOnScreen().
Sono titubante nel chiamare le unità di evento / visualizzazione desiderate "pixel" poiché evidentemente ci sono diverse nozioni di "pixel" sul mio telefono in varie modalità e non si aggiungono a una storia coerente.
Vedo che è stato chiesto e risposto molto su StackOverflow e altrove, ma nessuna delle risposte funziona sul mio telefono (Droid 4, Android 4.1.2) in tutte le modalità:
- Posso scoprire la larghezza dello schermo in modo programmatico nell'app per Android?
- Come posso ottenere ScreenSize a livello di codice in Android
- Set Android Visualizza la visibilità a livello di codice in base alle dimensioni dello schermo
- Come posso ottenere l'altezza dello schermo in Android?
- Ottieni l'altezza dello schermo in 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 e impostazione di larghezza e altezza a livello di codice in unità 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
(Wow!)
Questo è per il codice della libreria che deve funzionare indipendentemente dal fatto che l'app sia in "modalità compatibilità schermo" (ovvero targetSdkVersion <= 10 nel manifest) o no, e inoltre non voglio fare alcuna ipotesi sulla posizione, la dimensione o l'esistenza della barra di stato o di qualsiasi altra decorazione dello schermo simile.
Ecco i fatti:
il mio telefono (un droide 4 con Android 4.1.2) ha 540x960 pixel fisici, cioè piccoli punti luminosi colorati.
la dimensione dello schermo nelle unità desiderate, dalla visualizzazione degli eventi tattili e dalla visualizzazione delle misurazioni, è 360x640 quando l'app è in modalità compatibilità schermo, 540x960 quando l'app non è in modalità compatibilità schermo. Questi sono i numeri che devo trovare a livello di codice, senza confondere eventi tattili o visualizzazioni per trovarli, ma ho estrema difficoltà a trovare qualsiasi API che restituisca questi numeri.
Gli oggetti Display e DisplayMetrics ottenuti in vari modi sostengono che le dimensioni dello schermo sono 540x960 "pixel" (indipendentemente dal fatto che siano compatibili o meno). Per essere precisi, tutti i seguenti dicono 540x960 per tutto il tempo: DisplayMetrics. {Larghezza, altezza} Pixel, Display.getSize (), Display.getRealSize (), Display.get {Larghezza, Altezza} (),
Gli oggetti di configurazione ottenuti in vari modi dicono tutti schermo {Larghezza, Altezza} Dp = 360x614 (sia in modalità schermo compatibile o meno). Non credo che rappresenti l'intero schermo, poiché le proporzioni sono errate. (Penso che sia l'intero schermo meno la barra di stato; ho bisogno di tutto lo schermo.) Penso che sia sicuro dire che l'intero schermo è 360x640 dp, anche se non conosco alcuna API che restituisca quel 640.
DisplayMetrics ottenuto in vari modi afferma che la "densità" è 1.0f quando è in modalità compatibilità schermo, 1.5f quando non è in modalità compatibilità schermo.
L'attività
getWindow().getAttributes().{width,height}non è utile poiché contiene in genereMATCH_PARENTanziché dimensioni effettive. Ma a quanto pare riesco a ottenere la risposta desiderata da un'attivitàgetWindow().getDecorView().getMeasured{Width,Height}()(il che è in realtà sorprendente poiché il decorView della finestra dell'attività non sembra occupare l'intero schermo; sembra che occupi lo schermo meno la barra di stato). Ma non voglio fare affidamento su questo perché se la finestra viene mai ridimensionata (appare la tastiera virtuale? Qualcuno chiama window.setAttributes ()? O forse non sono affatto in un'attività), questo sarà chiaramente tutto sbagliato.
Capisco che la seguente formula dovrebbe contenere: pixel = densità dp * che sembra concordare con tutti i numeri riportati ((3), (4), (5) sopra) quando non è in modalità compatibilità schermo: 540x960 = 360x640 * 1.5 Ma nella modalità di compatibilità dello schermo non si somma: 540x960! = 360x640 * 1 Quindi, qualcosa non va.
La spiegazione più semplice, penso, è che i metodi elencati in (3) sopra stanno semplicemente dando la risposta sbagliata per "pixel" quando in modalità compatibilità schermo - cioè, erano destinati a restituire "pixel" 360x640 ma sono erroneamente restituendo invece 540x960. Ma potrebbero esserci altri modi di vederlo.
In ogni caso, ottenere i numeri desiderati indipendentemente dalla modalità, dai pezzi del puzzle sopra, è sicuramente un puzzle complicato. Ho trovato un modo che sembra funzionare sul mio telefono in entrambe le modalità, ma è estremamente complicato e si basa su due ipotesi che sembrano ancora piuttosto traballanti (come descritto nei commenti sul codice di seguito).
Ecco la mia ricetta:
/** 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);
}
C'è un modo migliore / più pulito per trovare le dimensioni dello schermo ??
DisplayMetricsnon venga mai aggiornata da tali modifiche. Ci sono problemi come questo già archiviati.