Pregunta

Creé algunos elementos personalizados y quiero colocarlos mediante programación en la esquina superior derecha ( n píxeles desde el borde superior y m 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 obtengo screenWidth y screenHeight en la Actividad principal?

¿Fue útil?

Solución

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 una Activity , puede obtener la Display predeterminada a través de WINDOW_SERVICE :

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

Si está en un fragmento y desea realizar esto, simplemente use Activity.WindowManager (en Xamarin.Android) o getActivity (). getWindowManager () (en java).

Antes de que se introdujera getSize (en el nivel 13 de API), podía usar los métodos getWidth y getHeight que 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 usar widthPixels para obtener información para:

  

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

Ejemplo :

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

Otros consejos

Una forma es:

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

Está en desuso, y debería probar el siguiente código en su lugar. Las primeras dos líneas de código le dan los objetos DisplayMetrics . Este objeto contiene los campos como heightPixels , widthPixels .

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

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

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 no ha sido presentado todavía (por ejemplo, en onCreate () ) puede configurar un ViewTreeObserver.OnGlobalLayoutListener con View.getViewTreeObserver (). addOnGlobalLayoutListener () y ponga el código relevante que necesita la dimensión de la vista allí. La devolución de llamada del oyente se llamará cuando se haya diseñado el diseño.

(respuesta de 2012, puede estar desactualizado) 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 en desuso eventualmente serán eliminados de los SDK más recientes, pero aunque todavía confiamos en que la mayoría de nuestros usuarios tengan Android 2.1, 2.2 y 2.3, esto es lo que nos queda.

He intentado todas las posibles "soluciones" sin éxito y me di cuenta de que Elliott Hughes '' Dalvik Explorer '' La aplicación 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 versiones de SO no compatibles):

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) {
}

La forma más simple:

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

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 result da la altura en el píxel.

Para acceso rápido

Ingrese la descripción de la imagen aquí

Para obtener más información acerca de la altura de Barra de título , Barra de navegación y Vista de contenido , mire Tamaños de pantalla del dispositivo Android .

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

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;
}

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

El siguiente ejemplo, modificado 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>

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.

¿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 (incluidos los decorados de pantalla, como la barra de estado o la barra de navegación de software) utilizando getRealMetrics , pero esto funciona solo en 17+.

¿Me estoy perdiendo algo?

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 usar para buscar otros atributos de una vista que se desconoce en su mayoría en el momento onCreate (), p. la posición desplazada, la posición escalada.

Encuentra el ancho y la altura de la pantalla:

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

Usando 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);
}

Usando el siguiente código en Actividad.

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

Encontré que esto hizo el truco.

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

Necesito decir que si no está en Activity , sino en View (o tiene una variable de View escriba en su ámbito) , no es necesario usar WINDOW_SERVICE . Entonces puede 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.

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);
    }
}

Para obtener las dimensiones de la pantalla, utilice las métricas 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;

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 " device-independent-pixels " ;, y reunir las respuestas desde aquí https://stackoverflow.com/a/ 17880012/253938 y aquí https://stackoverflow.com/a/6656774/253938 se me ocurrió esto:

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

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;

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;
}

Puede obtener el tamaño de altura usando:

getResources().getDisplayMetrics().heightPixels;

y el tamaño de ancho usando

getResources().getDisplayMetrics().widthPixels; 

Para quién está buscando dimensión de pantalla utilizable sin Barra de estado y 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);
}

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 el ancho y la altura de acuerdo con la resolución de tu pantalla.

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;
}

Hay momentos en los que necesita conocer las dimensiones precisas del espacio disponible para un diseño cuando se encuentra en una actividad onCreate. 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();
    }
}    

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_parent. (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" >

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

Tengo una actividad de pantalla de presentación con LinearLayout como vista raíz que tiene match_parent para su ancho & amp; altura. Este es el código en el método onCreate () de esa actividad. Utilizo estas medidas en todas las demás actividades de la aplicación.

int displayWidth = getRawDisplayWidthPreHoneycomb();
int rawDisplayHeight = getRawDisplayHeightPreHoneycomb();
int usableDisplayHeight = rawDisplayHeight - getStatusBarHeight();
pf.setScreenParameters(displayWidth, usableDisplayHeight);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    LinearLayout myView = (LinearLayout) findViewById(R.id.splash_view);
    myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            if (left == 0 && top == 0 && right == 0 && bottom == 0) {
                return;
            }
            int displayWidth = Math.min(right, bottom);
            int usableDisplayHeight = Math.max(right, bottom);
            pf.setScreenParameters(displayWidth, usableDisplayHeight);
        }
    });
}

Estas son las implementaciones para los métodos que ve que se llaman arriba:

private int getRawDisplayWidthPreHoneycomb() {
    WindowManager windowManager = getWindowManager();
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics displayMetrics = new DisplayMetrics();
    display.getMetrics(displayMetrics);

    int widthPixels = displayMetrics.widthPixels;
    int heightPixels = displayMetrics.heightPixels;

    return Math.min(widthPixels, heightPixels);
}

private int getRawDisplayHeightPreHoneycomb() {
    WindowManager w = getWindowManager();
    Display d = w.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    d.getMetrics(metrics);

    int widthPixels = metrics.widthPixels;
    int heightPixels = metrics.heightPixels;

    return Math.max(widthPixels, heightPixels);
}

public int getStatusBarHeight() {
    int statusBarHeight = 0;

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

    return statusBarHeight;
}

Esto da como resultado el alto y el ancho de la pantalla utilizable, excluyendo cualquier tipo de barras (barra de estado, barra de navegación), para todas las versiones API y diferentes tipos de dispositivos (teléfonos y tabletas).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top