sábado, 10 de marzo de 2012

Como obtener la resolución de pantalla y densidad en Aplicaciones Android


En caso de una aplicación que no use la compatibilidad de resoluciones por xml (layout small, layout normal, layout large y ahora xlarge) para adaptarse a las distintas resoluciones de cada pantalla, la api de Android cuenta con la clase Display que se encuentra en el package View y la clase DisplayMetrics que está en util.
En su aplicación vas a poder controlar cada gráfico (drawable) de acuerdo al ratio de la pantalla y de su densidad. Existe en Android la relación DPI / pixeles que permite siempre medir en densidades en las distintas resoluciones (en pixel). Se trabaja con la unidad métrica Dip(Density-independent pixel) que equivale más o menos a 1.5 pixel ( escala ) para todo lo que es drawable y el cuerpo de las tipografías.
Con el Objeto Display entonces podemos calcular cuánto mide la pantalla del dispositivo en que se ve la aplicación, su orientación en el momento que se abre, el refreshrate de la pantalla.
Con el objeto DisplayMetrics, obtenemos la densidad por dpi y si el equipo es High Density o Low Density, Medium Density. De acuerdo a su densidad los valores en dip representan distintos valores en pixeles.
Por ejemplo:
300 dip en HVGA (320×480) son 300 pixeles
300 dip en WVGA800 (480×800) son 450 pixeles
1 dip en HVGA (480×854) son 1.5 pixeles
Teniendo en cuenta que la densidad de pantallas HVGA (HDPI) es superior a 240 dpi y hasta 300 dpi, y la densidad de WGA (LDPI) es de 160 dpi, existe ahora XHDPI que es a partir de 300 dpi y superior.
La relacion para averiguar a qué equivale un pixel según la densidad es:
pixels = dps * (scaleDensity / screendensity)
Para probar con un ejemplo, tenemos este código que permite encontrar a mano los pixeles según las resoluciones de pantalla cuando sólo tenemos los dps(Density-independent pixel) de un drawable, layout, tipografía:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package com.msalvetti.example.resolution;
 
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        TextView text1 = (TextView) findViewById(R.id.text1);
        TextView text2 = (TextView) findViewById(R.id.text2);
        TextView text3 = (TextView) findViewById(R.id.text3);
        TextView text4 = (TextView) findViewById(R.id.text4);
        TextView text5 = (TextView) findViewById(R.id.text5);
        Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
 
        text1.setText("Ancho de la Pantalla " + Integer.toString(display.getWidth()));
        text2.setText("Alto de la pantalla " + Integer.toString(display.getHeight()));
        text3.setText("Densidad de la pantalla (dpi) " + getResources().getDisplayMetrics().densityDpi);
 
        float scale = getApplicationContext().getResources().getDisplayMetrics().density;
        text4.setText("Escala " + Float.toString(getApplicationContext().getResources().getDisplayMetrics().density));
 
        // buscando los pixeles a partir de dips con la densidad
        int dips = 200;
        float pixelBoton = 0;
        float scaleDensity = 0;
 
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
 
        switch(metrics.densityDpi)
        {
        case DisplayMetrics.DENSITY_HIGH: //HDPI
            text5.setText("Alta Densidad");
            scaleDensity = scale * 240;
            pixelBoton = dips * (scaleDensity / 240);
            break;
        case DisplayMetrics.DENSITY_MEDIUM: //MDPI
            text5.setText("mediana Densidad");
            scaleDensity = scale * 160;
            pixelBoton = dips * (scaleDensity / 160);
            break;
 
        case DisplayMetrics.DENSITY_LOW:  //LDPI
            text5.setText("baja Densidad");
            scaleDensity = scale * 120;
            pixelBoton = dips * (scaleDensity / 120);
            break;
        }
        Log.d(getClass().getSimpleName(), "pixels:"+Float.toString(pixelBoton));
 
    }
}
y una forma más directa de descubrir lo mismo con TypedValue:
?
1
2
3
Resources resources = getResources();
Int dips = 200;
float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dips, resourses.getDisplayMetrics());
Gracias por comentar este post por si lo quieren aplicar en ejemplos precisos.

No hay comentarios:

Publicar un comentario