¿Cómo puedo averiguar el tamaño de mi pantalla mediante programación, en las unidades utilizadas por eventos táctiles y Ver medición / diseño? En otras palabras, quiero las coordenadas de la esquina inferior derecha de la pantalla, en el sistema de coordenadas utilizado por los eventos táctiles
getRawX()/getRawY()y View.getLocationOnScreen().
Dudo en llamar a las unidades de evento / vista deseadas "píxeles", ya que evidentemente hay varias nociones de "píxeles" en mi teléfono en varios modos, y no se suman a una historia coherente.
Veo que esto se ha preguntado y respondido mucho en stackoverflow y en otros lugares, pero ninguna de las respuestas realmente funciona en mi teléfono (droid 4, android 4.1.2) en todos los modos:
- ¿Puedo averiguar el ancho de la pantalla mediante programación en la aplicación de Android?
- ¿Cómo obtengo ScreenSize mediante programación en Android?
- Android establece la visibilidad de la vista mediante programación según el tamaño de la pantalla
- ¿Cómo obtengo la altura de la pantalla en Android?
- Obtenga la altura de la pantalla en Android
- https://groups.google.com/forum/#!topic/android-developers/IpxnfvDFrpc
- http://shuklaxyz.blogspot.com/2012/02/how-to-programmatic-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 y configuración de ancho y alto mediante programación en unidades dp
- 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-programmatic
(¡Guau!)
Esto es para el código de biblioteca que debe funcionar independientemente de si la aplicación está en "modo de compatibilidad de pantalla" (es decir, targetSdkVersion <= 10 en el manifiesto) o no, y tampoco quiero hacer suposiciones sobre la posición, el tamaño , o la existencia de la barra de estado o cualquier otra decoración de pantalla similar.
Aquí están los hechos:
mi teléfono (un droid 4 con Android 4.1.2) tiene 540x960 píxeles físicos, es decir, pequeños puntos brillantes de colores.
El tamaño de la pantalla en las unidades deseadas, desde mirar eventos táctiles y Ver mediciones, es 360x640 cuando la aplicación está en modo de compatibilidad de pantalla, 540x960 cuando la aplicación no está en modo de compatibilidad de pantalla. Estos son los números que necesito encontrar mediante programación, sin alterar los eventos táctiles o las Vistas para encontrarlos, pero tengo dificultades extremas para encontrar cualquier API que devuelva estos números.
Los objetos Display y DisplayMetrics obtenidos de varias maneras afirman que el tamaño de la pantalla es de 540x960 "píxeles" (ya sea en modo de compatibilidad de pantalla o no). Para ser específicos, los siguientes dicen 540x960 todo el tiempo: DisplayMetrics. {Width, height} Pixels, Display.getSize (), Display.getRealSize (), Display.get {Width, Height} (),
Todos los objetos de configuración obtenidos de varias maneras dicen pantalla {Ancho, Altura} Dp = 360x614 (ya sea en modo de compatibilidad de pantalla o no). No creo que eso represente toda la pantalla, ya que la relación de aspecto es incorrecta. (Creo que es toda la pantalla menos la barra de estado; necesito toda la pantalla). Creo que es seguro decir que toda la pantalla tiene 360x640 dp, aunque no conozco ninguna API que devuelva esos 640.
DisplayMetrics obtenido de varias maneras dice que la "densidad" es 1.0f cuando está en modo de compatibilidad de pantalla, 1.5f cuando no está en modo de compatibilidad de pantalla.
La actividad
getWindow().getAttributes().{width,height}no es útil, ya que generalmente contieneMATCH_PARENTmás que los tamaños reales. Pero aparentemente puedo obtener la respuesta deseada de una actividadgetWindow().getDecorView().getMeasured{Width,Height}()(lo cual es realmente sorprendente ya que la decoración de la ventana de la actividad no parece estar ocupando toda la pantalla; parece que está ocupando la pantalla menos la barra de estado). Pero no quiero confiar en esto porque si la ventana alguna vez cambia de tamaño (¿aparece un teclado virtual? ¿Alguien que llama a window.setAttributes ()? incorrecto.
Entiendo que se supone que debe contener la siguiente fórmula: píxeles = dp * densidad Eso parece estar de acuerdo con todos los números informados ((3), (4), (5) arriba) cuando no está en modo de compatibilidad de pantalla: 540x960 = 360x640 * 1.5 Pero en el modo de compatibilidad de pantalla no suma: 540x960! = 360x640 * 1 Entonces, algo está mal.
Creo que la explicación más simple es que los métodos enumerados en (3) anteriores simplemente dan la respuesta incorrecta para "píxeles" cuando están en modo de compatibilidad de pantalla, es decir, estaban destinados a devolver 360x640 "píxeles", pero son incorrectos devolviendo 540x960 en su lugar. Pero puede haber otras formas de verlo.
En cualquier caso, obtener los números deseados independientemente del modo, de las piezas del rompecabezas anteriores, es ciertamente un rompecabezas complicado. He encontrado una forma que parece funcionar en mi teléfono en ambos modos, pero es extremadamente tortuosa y se basa en dos suposiciones que todavía parecen bastante inestables (como se describe en los comentarios del código a continuación).
Aquí está mi receta:
/** 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);
}
¿Hay alguna forma mejor / más limpia de encontrar el tamaño de la pantalla?
DisplayMetricsnunca se actualice de dichos cambios. Hay problemas como este ya archivados.