Cómo obtener dimensiones de pantalla como píxeles en Android


1843

Creé algunos elementos personalizados y quiero colocarlos mediante programación en la esquina superior derecha ( npíxeles desde el borde superior ym píxeles desde el borde derecho). Por lo tanto, necesito obtener el ancho y la altura de la pantalla y luego establecer la posición:

int px = screenWidth - m;
int py = screenHeight - n;

¿Cómo llego screenWidthy screenHeighten la Actividad principal?


Use dp en lugar de px. porque distorsionará su diseño con otros dispositivos ..
Jawad Zeb

No olvide multiplicar por getResources (). GetDisplayMetrics (). Densidad para tener en cuenta el escalado de la pantalla
jmaculate

Esto demuestra que la respuesta más votada no siempre es la mejor (y mucha gente repite las respuestas para el representante). En lugar de getSize y el combo getWidth / getHeight en desuso (ignorando errores), intente con Balaji.K's getMetrics. El comentario de Nik en su respuesta incluso explica getDisplayMetricsconsiderar el tamaño del sistema / barra de estado. También puede usar densidad como jmaculate y LoungeKatt explicó que tiene el valor EXACTO : DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;Probado en Android v2.2 (API 8) y v4.0 con buenos resultados y sin errores / advertencias .
Brazo

DisplayMetrics displaymetrics = new DisplayMetrics (); getWindowManager (). getDefaultDisplay (). getMetrics (displaymetrics); int height = displaymetrics.heightPixels; int ancho = displaymetrics.widthPixels;
Azahar

Otra forma de obtener los DisplayMetrics: Resources.getSystem().getDisplayMetrics(). No necesitarás un Contextpara conseguirlos.
Täg

Respuestas:


3479

Si desea las dimensiones de visualización en píxeles, puede usar getSize:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

Si no está en un Activitypuede obtener el valor predeterminado a Displaytravés de WINDOW_SERVICE:

WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();

Si está en un fragmento y quiere lograr esto, simplemente use Activity.WindowManager (en Xamarin.Android) o getActivity (). GetWindowManager () (en java).

Antes de que getSizese introdujera (en el nivel 13 de la API), podría usar los métodos getWidthy getHeightque ahora están en desuso:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();  // deprecated
int height = display.getHeight();  // deprecated

Sin embargo, para el caso de uso que está describiendo, un margen / relleno en el diseño parece más apropiado.

Otra forma es: DisplayMetrics

Una estructura que describe información general sobre una pantalla, como su tamaño, densidad y escala de fuente. Para acceder a los miembros de DisplayMetrics, inicialice un objeto como este:

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

Podemos utilizar widthPixelspara obtener información para:

"El ancho absoluto de la pantalla en píxeles".

Ejemplo:

Log.d("ApplicationTagName", "Display width in px is " + metrics.widthPixels);

13
getWidth () o getSize ()? ¿Qué usaría si necesito que mi aplicación se ejecute en API <13 y API> 13?
Carol

52
pruebe {display.getSize (tamaño); ancho = tamaño.x; altura = tamaño.y; } catch (NoSuchMethodError e) {ancho = display.getWidth (); height = display.getHeight (); }
Arnaud

248
No veo por qué quieres usar try/catchpara tal cheque. ¿Por qué no simplemente usar if (android.os.Build.VERSION.SDK_INT >= 13)sin ninguna excepción lanzada? Pienso try/catchen un flujo normal de aplicaciones como una mala práctica.
Patrik

2
@ A-Live, entonces la aplicación también se rompería (pero no se bloquearía). Sin embargo, los desarrolladores debemos comprobar previamente una nueva versión del sistema operativo y esto puede ocultar un problema. También con este argumento uno podría / debería rodear cada pocas líneas de código con try / catch, que en mi opinión es una mala práctica como ya se mencionó.
Patrik

11
¿Qué pasa si desea obtener el tamaño de la pantalla, excluyendo la barra de navegación y / o la barra de notificaciones
Desarrollador de Android

375

Una forma es:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

Está en desuso y, en su lugar, debe probar el siguiente código. Las dos primeras líneas de código te dan los DisplayMetricsobjetos. Este objeto contiene los campos como heightPixels, widthPixels.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int height = metrics.heightPixels;
int width = metrics.widthPixels;

14
Tenga en cuenta que las métricas (ancho, alto) cambian según la rotación del dispositivo.
Tony Chan

8
Las métricas devolverán el tamaño de la pantalla, pero HoneyComb y más, su actividad tendrá menos espacio que el que se devuelve debido a la barra del sistema.
Guy

3
@Guy depende de tu implementación. Puede ocultar la barra de estado: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Hagai L

79
También existe de esta manera: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels
Nik

escala flotante final = getResources (). getDisplayMetrics (). densidad; ancho int = (int) (metrics.widthPixels * scale + 0.5f); - Debe tener en cuenta la densidad del dispositivo al hacerlo de esa manera.
Carrito abandonado

120

Puede que no responda su pregunta, pero podría ser útil saber (lo estaba buscando yo mismo cuando llegué a esta pregunta) que si necesita una dimensión de Vista pero su código se está ejecutando cuando su diseño aún no se ha establecido (por ejemplo, en onCreate()) puede configurar un ViewTreeObserver.OnGlobalLayoutListenercon View.getViewTreeObserver().addOnGlobalLayoutListener()y poner el código relevante que necesita la dimensión de la vista allí. Se llamará a la devolución de llamada del oyente cuando se haya diseñado el diseño.


o simplemente escriba view.post
Lukas Hanacek

No obstante, view.post no está garantizado para funcionar. Es solo una solución.
marsbear

@marsbear, ¿dónde dice que View.post()no está garantizado que funcione? Tengo curiosidad porque también confío en este método para obtener el tamaño de una Vista después del diseño y no sabía que no era confiable.
Tony Chan

@Turbo Digo eso: p Utilizamos esa solución antes y resultó ser poco confiable. Esa solución se basa en el supuesto de que el diseño inicial se realiza dentro del mismo turno de UIThread que la inicialización. Por lo tanto, puede programar su código para que se ejecute antes del próximo giro de la interfaz de usuario a través de post () y estar bien. Resultó que el diseño podría tomar aún más tiempo bajo ciertas circunstancias y la vista aún no se trazó cuando se ejecutó el código publicado. Lo que hago ahora es agregar el ViewTreeObserver en onCreate y eliminarlo después del primer onLayout. Inicia tus cosas durante ese primer diseño.
marsbear

@marsbear, ¿importa de Viewdónde obtengas ViewTreeObserver? ¿O todos comparten el mismo?
Tony Chan

109

(Respuesta de 2012, puede estar desactualizada) Si desea admitir la versión anterior de Honeycomb, necesitará una compatibilidad con versiones anteriores antes de la API 13. Algo así como:

int measuredWidth = 0;
int measuredHeight = 0;
WindowManager w = getWindowManager();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    Point size = new Point();
    w.getDefaultDisplay().getSize(size);
    measuredWidth = size.x;
    measuredHeight = size.y;
} else {
    Display d = w.getDefaultDisplay();
    measuredWidth = d.getWidth();
    measuredHeight = d.getHeight();
}

Por supuesto, los métodos obsoletos se eliminarán de los SDK más recientes, pero si bien confiamos en que la mayoría de nuestros usuarios tengan Android 2.1, 2.2 y 2.3, esto es lo que nos queda.


Sí, esto fue en 2012.
digiphd

lo siento, permíteme aclarar lo que quise decir. Es muy poco probable que alguien soporte API <14 a partir del 22/06/2015
sudocoder

69

He intentado todas las "soluciones" posibles sin éxito y me di cuenta de que la aplicación "Dalvik Explorer" de Elliott Hughes siempre muestra la dimensión correcta en cualquier dispositivo Android / versión del sistema operativo. Terminé mirando su proyecto de código abierto que se puede encontrar aquí: https://code.google.com/p/enh/

Aquí está todo el código relevante:

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
try {
    // used when 17 > SDK_INT >= 14; includes window decorations (statusbar bar/menu bar)
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
try {
    // used when SDK_INT >= 17; includes window decorations (statusbar bar/menu bar)
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

EDITAR: versión ligeramente mejorada (evite las excepciones de disparo en la versión de SO no compatible):

WindowManager w = activity.getWindowManager();
Display d = w.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
d.getMetrics(metrics);
// since SDK_INT = 1;
widthPixels = metrics.widthPixels;
heightPixels = metrics.heightPixels;
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)
try {
    widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);
    heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);
} catch (Exception ignored) {
}
// includes window decorations (statusbar bar/menu bar)
if (Build.VERSION.SDK_INT >= 17)
try {
    Point realSize = new Point();
    Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);
    widthPixels = realSize.x;
    heightPixels = realSize.y;
} catch (Exception ignored) {
}

99
Esta es la única publicación aquí que tiene en cuenta las decoraciones de las ventanas (barra de estado / barra de menú). funcionó muy bien para mí
Andy Cochrane

55
Impresionante, sin embargo, nunca debería haber esperado excepciones de lógica de negocios. Disparar con excepción (incluso cuando es atrapado) es horrible para el rendimiento. Además, está haciendo más trabajo del necesario si SDK_INT es> 13. En su lugar, solo debe agregar algunos ifs en Build.VERSION.SDK_INT.
Erik B

3
@Erik B, estoy de acuerdo. Agregué una versión mejorada. Aún así, dejé la parte "desde SDK 1" por si algo sale mal en try / catch (he visto muchas cosas malas en Android, especialmente cuando crees que es imposible que algo salga mal, así que me gusta mantenerlo a salvo :)) . De todos modos, no debería haber demasiada sobrecarga, ya que este cálculo debe hacerse solo una vez (por ejemplo, los valores podrían mantenerse en algunos atributos estáticos).
Dragan Marjanović

8
Tenga en cuenta que este código tiene licencia bajo GPL v3, lo que tiene implicaciones para su uso en aplicaciones de producción.
TalkLittle

GPL y dependiendo de la reflexión para llamar a métodos que podrían no estar presentes en futuras versiones de Android. Mhhh
Michel

47

La forma más simple:

 int screenHeight = getResources().getDisplayMetrics().heightPixels;
 int screenWidth = getResources().getDisplayMetrics().widthPixels; 

46

Para acceder a la altura de la barra de estado para dispositivos Android, preferimos una forma programática para obtenerlo:

Código de muestra

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    result = getResources().getDimensionPixelSize(resId);
}

La variable resultda la altura en el píxel.

Para un acceso rápido

Ingrese la descripción de la imagen aquí

Para obtener más información sobre la altura de Title bar, Navigation bary Content View, por favor, mire los tamaños de pantalla del dispositivo Android .


¡Justo lo que necesitaba! getResources().getDisplayMetrics().heightPixels + resultda la altura real de pantalla completa. La respuesta de Dragan Marjanović también funciona, pero prefiero esta solución mucho más corta y simple.
Michel

Este enfoque está desactualizado a partir de Android Marshmallow. La altura de la barra de estado puede cambiar desde el dispositivo o la versión de Android. Mejor uso OnApplyWindowInsetsListener.
Heinrich

32

Primero obtenga la vista (por ejemplo, by findViewById()) y luego puede usar getWidth () en la vista misma.


3
Así es como la documentación te dice que lo hagas ... pero no tiene sentido si NO estás usando una vista. puede estar usando otra cosa, por ejemplo, mglsurfaceview.
gcb

2
esto es mejor ya que la vista principal puede no ser del tamaño de la pantalla. Pero asegúrese de que esto se haga en un punto en el que la vista del tamaño de la consulta ya se haya distribuido, que generalmente no estará en onCreate (). Puede usar una devolución de llamada personalizada desde onWindowFocusChanged (boolean hasFocus) que se llamará después de que se hayan medido todas las vistas, etc., asegurando que no recibirá dimensiones incorrectas para la vista que le interesa ...
Dori

27

Tengo dos funciones, una para enviar el contexto y la otra para obtener el alto y el ancho en píxeles:

public static int getWidth(Context mContext){
    int width=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        width = size.x;
    }
    else{
        width = display.getWidth();  // Deprecated
    }
    return width;
}

y

public static int getHeight(Context mContext){
    int height=0;
    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    if(Build.VERSION.SDK_INT>12){
        Point size = new Point();
        display.getSize(size);
        height = size.y;
    }
    else{
        height = display.getHeight();  // Deprecated
    }
    return height;
}

Debe agregar @SuppressLint("NewApi")justo encima de la firma de la función para poder compilar.
Adil Malik

Creo que es mejor obtener la altura y el ancho de una vez en lugar de en llamadas separadas a las API porque de lo contrario podrían estar fuera de sincronización. Esto podría suceder si la orientación de la pantalla cambia mientras se ejecuta el código.
Sam

17

Para escalar dinámicamente usando XML hay un atributo llamado "android: layout_weight"

El siguiente ejemplo, modificado a partir de la respuesta de synic en este hilo , muestra un botón que ocupa el 75% de la pantalla (peso = .25) y una vista de texto que ocupa el 25% restante de la pantalla (peso = .75).

<LinearLayout android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".25"
        android:text="somebutton">

    <TextView android:layout_width="fill_parent"
        android:layout_height="Wrap_content"
        android:layout_weight=".75">
</LinearLayout>

17

Este es el código que uso para la tarea:

// `activity` is an instance of Activity class.
Display display = activity.getWindowManager().getDefaultDisplay();
Point screen = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    display.getSize(screen);
} else {            
    screen.x = display.getWidth();
    screen.y = display.getHeight();
}

Parece lo suficientemente limpio y, sin embargo, se encarga de la degradación.


17

¿No es esta una solución mucho mejor? DisplayMetrics viene con todo lo que necesita y funciona desde la API 1.

public void getScreenInfo(){
    DisplayMetrics metrics = new DisplayMetrics();
    getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);

    heightPixels = metrics.heightPixels;
    widthPixels = metrics.widthPixels;
    density = metrics.density;
    densityDpi = metrics.densityDpi;
}

También puede obtener la visualización real (incluidas las decoraciones de pantalla, como la barra de estado o la barra de navegación del software) usando getRealMetrics , pero esto funciona solo en 17+.

¿Me estoy perdiendo de algo?


1
No resta espacio para los controles en pantalla (como en tabletas o dispositivos Nexus). Además, obtengo un valor diferente (750 vs 800) en mi tableta de 10 ", dependiendo de si la Actividad está activa cuando se realiza el cálculo. Pero para mis propósitos, esto está más que bien. ¡Gracias!
Steven L

15

Solo agrego a la respuesta de Francesco. El otro observador que es más apto, si desea averiguar la ubicación en la ventana o la ubicación en la pantalla, es ViewTreeObserver.OnPreDrawListener ()

Esto también se puede utilizar para encontrar otros atributos de una vista que es desconocida en su mayoría en el momento onCreate (), por ejemplo, la posición desplazada, la posición escalada.


15

Usando el siguiente código en Actividad.

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int height = metrics.heightPixels;
int wwidth = metrics.widthPixels;

15

Encuentra el ancho y la altura de la pantalla:

width = getWindowManager().getDefaultDisplay().getWidth();
height = getWindowManager().getDefaultDisplay().getHeight();

Con esto, podemos obtener el SDK 13 más reciente y superior.

// New width and height
int version = android.os.Build.VERSION.SDK_INT;
Log.i("", " name == "+ version);
Display display = getWindowManager().getDefaultDisplay();
int width;
if (version >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
    Log.i("width", "if =>" +width);
}
else {
    width = display.getWidth();
    Log.i("width", "else =>" +width);
}

15
DisplayMetrics dimension = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dimension);
int w = dimension.widthPixels;
int h = dimension.heightPixels;

12

Encontré que esto hizo el truco.

Rect dim = new Rect();
getWindowVisibleDisplayFrame(dim);

55
Genial, pero es una cosa aterradora sobre este método en el código fuente: este comentario
Norbert

12

Es necesario decir que si no está en Activity, pero en View(o tiene una variable de Viewtipo en su alcance), no es necesario usarWINDOW_SERVICE . Entonces puedes usar al menos dos formas.

Primero:

DisplayMetrics dm = yourView.getContext().getResources().getDisplayMetrics();

Segundo:

DisplayMetrics dm = new DisplayMetrics();
yourView.getDisplay().getMetrics(dm);

Todos estos métodos que llamamos aquí no están en desuso.


12
public class AndroidScreenActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                                   + dm.widthPixels
                                   + " x "
                                   + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
    }
}

12

Para obtener las dimensiones de la pantalla, utilice metrices de visualización

DisplayMetrics displayMetrics = new DisplayMetrics();
if (context != null) 
      WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
      Display defaultDisplay = windowManager.getDefaultDisplay();
      defaultDisplay.getRealMetrics(displayMetrics);
    }

Obtenga la altura y el ancho en píxeles

int width  =displayMetrics.widthPixels;
int height =displayMetrics.heightPixels;

9

Esta no es una respuesta para el OP, ya que quería las dimensiones de la pantalla en píxeles reales. Quería las dimensiones en "píxeles independientes del dispositivo", y reuniendo las respuestas desde aquí https://stackoverflow.com/a/17880012/253938 y aquí https://stackoverflow.com/a/6656774/253938 se me ocurrió con este:

    DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
    int dpHeight = (int)(displayMetrics.heightPixels / displayMetrics.density + 0.5);
    int dpWidth = (int)(displayMetrics.widthPixels / displayMetrics.density + 0.5);

9

Puede obtener el tamaño de altura usando:

getResources().getDisplayMetrics().heightPixels;

y el tamaño del ancho usando

getResources().getDisplayMetrics().widthPixels; 

8

Hay una forma no obsoleta de hacer esto usando DisplayMetrics (API 1), que evita el desorden try / catch:

 // initialize the DisplayMetrics object
 DisplayMetrics deviceDisplayMetrics = new DisplayMetrics();

 // populate the DisplayMetrics object with the display characteristics
 getWindowManager().getDefaultDisplay().getMetrics(deviceDisplayMetrics);

 // get the width and height
 screenWidth = deviceDisplayMetrics.widthPixels;
 screenHeight = deviceDisplayMetrics.heightPixels;

8

Envolvería el código getSize de esta manera:

@SuppressLint("NewApi")
public static Point getScreenSize(Activity a) {
    Point size = new Point();
    Display d = a.getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        d.getSize(size);
    } else {
        size.x = d.getWidth();
        size.y = d.getHeight();
    }
    return size;
}

Esto se bloquea en un emulador que ejecuta Android 4.0 (API 14).
jww

6

Para quién está buscando una dimensión de pantalla utilizable sin la Barra de estado y la Barra de acción (también gracias a la respuesta de Swapnil):

DisplayMetrics dm = getResources().getDisplayMetrics();
float screen_w = dm.widthPixels;
float screen_h = dm.heightPixels;

int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resId > 0) {
    screen_h -= getResources().getDimensionPixelSize(resId);
}

TypedValue typedValue = new TypedValue();
if(getTheme().resolveAttribute(android.R.attr.actionBarSize, typedValue, true)){
    screen_h -= getResources().getDimensionPixelSize(typedValue.resourceId);
}

6

Primero cargue el archivo XML y luego escriba este código:

setContentView(R.layout.main);      
Display display = getWindowManager().getDefaultDisplay();
final int width = (display.getWidth());
final int height = (display.getHeight());

Muestra ancho y alto según la resolución de tu pantalla.


6

Siga los métodos a continuación:

public static int getWidthScreen(Context context) {
    return getDisplayMetrics(context).widthPixels;
}

public static int getHeightScreen(Context context) {
    return getDisplayMetrics(context).heightPixels;
}

private static DisplayMetrics getDisplayMetrics(Context context) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    wm.getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics;
}

6

Kotlin

fun getScreenHeight(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.heightPixels
}

fun getScreenWidth(activity: Activity): Int {
    val metrics = DisplayMetrics()
    activity.windowManager.defaultDisplay.getMetrics(metrics)
    return metrics.widthPixels
}

5

Hay momentos en los que necesita conocer las dimensiones precisas del espacio disponible para un diseño cuando se encuentra en una actividad en el sitio. Después de pensarlo, resolví esta forma de hacerlo.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startActivityForResult(new Intent(this, Measure.class), 1);
        // Return without setting the layout, that will be done in onActivityResult.
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -1);
        // Width is now set to the precise available width, and a layout can now be created.            ...
    }
}

public final class Measure extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
       // Create a LinearLayout with a MeasureFrameLayout in it.
        // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
        LinearLayout linearLayout = new LinearLayout(this);
        LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
        measureFrameLayout.setLayoutParams(matchParent);
        linearLayout.addView(measureFrameLayout);
        this.addContentView(linearLayout, matchParent);
        // measureFrameLayout will now request this second activity to finish, sending back the width.
    }

    class MeasureFrameLayout extends FrameLayout {
        boolean finished = false;
        public MeasureFrameLayout(Context context) {
            super(context);
        }

        @SuppressLint("DrawAllocation")
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (finished) {
                return;
            }
            finished = true;
            // Send the width back as the result.
            Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
            Measure.this.setResult(Activity.RESULT_OK, data);
            // Tell this activity to finish, so the result is passed back.
            Measure.this.finish();
        }
    }
}

Si por alguna razón no desea agregar otra actividad al manifiesto de Android, puede hacerlo de esta manera:

public class MainActivity extends Activity {
    static Activity measuringActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            extras = new Bundle();
        }
        int width = extras.getInt("Width", -2);
        if (width == -2) {
            // First time in, just start another copy of this activity.
            extras.putInt("Width", -1);
            startActivityForResult(new Intent(this, MainActivity.class).putExtras(extras), 1);
            // Return without setting the layout, that will be done in onActivityResult.
            return;
        }
        if (width == -1) {
            // Second time in, here is where the measurement takes place.
            // Create a LinearLayout with a MeasureFrameLayout in it.
            // Just putting a subclass of LinearLayout in works fine, but to future proof things, I do it this way.
            LinearLayout linearLayout = new LinearLayout(measuringActivity = this);
            LinearLayout.LayoutParams matchParent = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            MeasureFrameLayout measureFrameLayout = new MeasureFrameLayout(this);
            measureFrameLayout.setLayoutParams(matchParent);
            linearLayout.addView(measureFrameLayout);
            this.addContentView(linearLayout, matchParent);
            // measureFrameLayout will now request this second activity to finish, sending back the width.
        }
    }

    @Override
    protected void onActivityResult (int requestCode, int resultCode, Intent data) {
        // Probably can never happen, but just in case.
        if (resultCode == RESULT_CANCELED) {
            finish();
            return;
        }
        int width = data.getIntExtra("Width", -3);
        // Width is now set to the precise available width, and a layout can now be created. 
        ...
    }

class MeasureFrameLayout extends FrameLayout {
    boolean finished = false;
    public MeasureFrameLayout(Context context) {
        super(context);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (finished) {
            return;
        }
        finished = true;
        // Send the width back as the result.
        Intent data = new Intent().putExtra("Width", MeasureSpec.getSize(widthMeasureSpec));
        MainActivity.measuringActivity.setResult(Activity.RESULT_OK, data);
        // Tell the (second) activity to finish.
        MainActivity.measuringActivity.finish();
    }
}    

Obviamente, también puede devolver la altura en el paquete también.
Steve Waring

5

Si no desea la sobrecarga de WindowManagers, Points o Displays, puede tomar los atributos de alto y ancho del elemento de vista superior en su XML, siempre que su altura y ancho estén configurados para emparejar_parente. (Esto es cierto siempre que su diseño ocupe toda la pantalla).

Por ejemplo, si su XML comienza con algo como esto:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/entireLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

Luego findViewById(R.id.entireLayout).getWidth()devolverá el ancho de la pantalla y findViewById(R.id.entireLayout).getHeight()devolverá la altura de la pantalla.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.