Come ottenere le dimensioni dello schermo come pixel in Android


1843

Ho creato alcuni elementi personalizzati e voglio posizionarli a livello di codice nell'angolo in alto a destra ( npixel dal bordo superiore e mpixel dal bordo destro). Pertanto ho bisogno di ottenere la larghezza e l'altezza dello schermo e quindi impostare la posizione:

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

Come ottengo screenWidthe screenHeightnell'attività principale?


Usa dp invece di px. perché distorcerà il layout con altri dispositivi ..
Jawad Zeb

Non dimenticare di moltiplicare per getResources (). GetDisplayMetrics (). Densità per tenere conto del ridimensionamento del display
jmaculate

Ciò dimostra che la risposta più votata non è sempre la migliore (e molte persone ripetono le risposte per rappresentante). Invece di getSize e la combinazione getWidth / getHeight deprecata (ignorando gli errori), prova Balaji.K's getMetrics. Il commento di Nik nella sua risposta spiega anche getDisplayMetricsdi considerare le dimensioni del sistema / barra di stato. Inoltre puoi usare la densità come spiegato in jmaculate e LoungeKatt per avere il valore EXACT : DisplayMetrics dm = getResources().getDisplayMetrics(); float fwidth = dm.density * dm.widthPixels;testato in Android v2.2 (API 8) e v4.0 con buoni risultati e senza errori / avvisi .
Armfoot,

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

Un altro modo per ottenere i DisplayMetrics: Resources.getSystem().getDisplayMetrics(). Non avrai bisogno di un Contextper ottenerli.
Data

Risposte:


3479

Se vuoi le dimensioni di visualizzazione in pixel puoi usare getSize:

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

Se non ci si trova, Activityè possibile ottenere l'impostazione predefinita Displaytramite WINDOW_SERVICE:

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

Se sei in un frammento e vuoi compierlo, usa solo Activity.WindowManager (in Xamarin.Android) o getActivity (). GetWindowManager () (in java).

Prima è getSizestato introdotto (nel livello API 13), è possibile utilizzare i metodi getWidthe getHeightche sono ora obsoleti:

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

Per il caso d'uso che stai descrivendo, tuttavia, un margine / riempimento nel layout sembra più appropriato.

Un altro modo è: DisplayMetrics

Una struttura che descrive informazioni generali su un display, come dimensioni, densità e ridimensionamento dei caratteri. Per accedere ai membri DisplayMetrics, inizializza un oggetto come questo:

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

Possiamo usare widthPixelsper ottenere informazioni per:

"La larghezza assoluta del display in pixel."

Esempio:

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

13
getWidth () o getSize ()? Cosa dovrei usare se avessi bisogno che la mia app funzionasse su API <13 e API> 13?
Carol

52
prova {display.getSize (size); larghezza = dimensione.x; altezza = taglia.y; } catch (NoSuchMethodError e) {width = display.getWidth (); height = display.getHeight (); }
Arnaud,

248
Non vedo perché vuoi usare try/catchquesto controllo? Perché non usare semplicemente if (android.os.Build.VERSION.SDK_INT >= 13)senza alcuna eccezione generata? Penso try/catcha un normale flusso di app come una cattiva pratica.
Patrik,

2
@A-Live quindi anche l'app si spezzerebbe (ma non si arresterebbe in modo anomalo). Noi sviluppatori dobbiamo comunque pre-controllare una nuova versione del sistema operativo e questo potrebbe semplicemente nascondere un problema. Anche con questo argomento si potrebbe / dovrebbe circondare ogni poche righe di codice con try / catch, che secondo me è una cattiva pratica come già detto.
Patrik,

11
cosa succede se si desidera ottenere le dimensioni dello schermo escludendo la barra di navigazione e / o la barra di notifica
sviluppatore Android

375

Un modo è:

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

È obsoleto e dovresti invece provare il seguente codice. Le prime due righe di codice ti danno gli DisplayMetricsoggetti. Questi oggetti contengono i campi come heightPixels, widthPixels.

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

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

14
Si noti che le metriche (larghezza, altezza) cambiano in base alla rotazione del dispositivo.
Tony Chan,

8
Le metriche restituiranno le dimensioni del display, ma HoneyComb e versioni successive, la tua attività avrà meno spazio di quanto restituito a causa della barra di sistema.
Guy

3
@Guy dipende dalla tua implementazione. È possibile nascondere la barra di stato: requestWindowFeature (Window.FEATURE_NO_TITLE); getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
Hagai L

79
Esiste anche in questo modo: getContext (). GetResources (). GetDisplayMetrics (). WidthPixels
Nik

float scala finale = getResources (). getDisplayMetrics (). densità; int width = (int) (metrics.widthPixels * scale + 0.5f); - Devi tenere conto della densità del dispositivo quando lo fai in questo modo.
Carrello abbandonato

120

Potrebbe non rispondere alla tua domanda, ma potrebbe essere utile sapere (stavo cercando me stesso quando sono arrivato a questa domanda) che se hai bisogno di una dimensione di View ma il tuo codice viene eseguito quando il suo layout non è stato ancora impostato (ad esempio in onCreate()) è possibile impostare un ViewTreeObserver.OnGlobalLayoutListenercon View.getViewTreeObserver().addOnGlobalLayoutListener()e inserire lì il codice pertinente che richiede la dimensione della vista. Il callback dell'ascoltatore verrà chiamato quando il layout sarà stato predisposto.


o semplicemente scrivi view.post
Lukas Hanacek,

view.post non è garantito per funzionare però. È solo una soluzione alternativa.
Marsbear,

@marsbear dove dice che View.post()non è garantito per funzionare? Sono curioso perché mi affido anche a questo metodo per ottenere le dimensioni di una vista dopo il layout e non ero consapevole che fosse inaffidabile.
Tony Chan,

@Turbo Dico che: p Abbiamo già usato questa soluzione alternativa e si è rivelato inaffidabile. Tale soluzione alternativa si basa sul presupposto che il layout iniziale venga eseguito all'interno dello stesso turno UIThread dell'inizializzazione. Quindi è possibile pianificare l'esecuzione del codice prima della svolta dell'interfaccia utente successiva tramite post () e va bene. Si è scoperto che il layout potrebbe richiedere ancora più tempo in determinate circostanze e la vista non era ancora layout quando è stato eseguito il codice pubblicato. Quello che faccio ora è aggiungere ViewTreeObserver in onCreate e rimuoverlo dopo il primo onLayout. Inizia le tue cose durante quel primo onLayout.
Marsbear

@marsbear è importante da Viewcosa ottieni ViewTreeObserver? O condividono tutti lo stesso?
Tony Chan,

109

(Risposta del 2012, potrebbe non essere aggiornata) Se si desidera supportare pre Honeycomb, è necessario inserire la compatibilità con le versioni precedenti prima dell'API 13. Qualcosa come:

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

Ovviamente i metodi obsoleti verranno eventualmente eliminati dagli SDK più recenti, ma mentre continuiamo a fare affidamento sulla maggior parte dei nostri utenti con Android 2.1, 2.2 e 2.3, questo è ciò che ci rimane.


Sì, è
successo

scusa, permettimi di chiarire cosa intendevo dire. È altamente improbabile che qualcuno supporti API <14 al 22/06/2015
sudocoder

69

Ho provato tutte le possibili "soluzioni" senza successo e ho notato che l'app "Dalvik Explorer" di Elliott Hughes mostra sempre la dimensione corretta su qualsiasi versione di dispositivo / sistema operativo Android. Ho finito per guardare il suo progetto open source che può essere trovato qui: https://code.google.com/p/enh/

Ecco tutto il codice rilevante:

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

EDIT: versione leggermente migliorata (evita di attivare eccezioni sulla versione del sistema operativo non supportata):

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

9
Questo è l'unico post qui che tiene conto delle decorazioni delle finestre (barra di stato / barra dei menu). ha funzionato alla grande per me.
Andy Cochrane,

5
Fantastico, tuttavia non avresti mai dovuto aspettarti eccezioni di incendio nella logica di business. L'eccezione sparare (anche quando catturato) è orribile per le prestazioni. Inoltre stai facendo più lavoro del necessario se SDK_INT è> 13. Invece, dovresti semplicemente aggiungere alcuni if ​​su Build.VERSION.SDK_INT.
Erik B,

3
@Erik B, sono d'accordo. Ho aggiunto una versione migliorata. Ho comunque lasciato la parte "dall'SDK 1" nel caso in cui qualcosa vada storto nel tentativo / cattura (ho visto molte cose brutte in Android, specialmente quando pensi che sia impossibile qualcosa che non vada, quindi mi piace tenerlo al sicuro :)) . In ogni caso, non dovrebbe esserci un sovraccarico eccessivo poiché questo calcolo dovrebbe essere eseguito una sola volta (ad esempio, i valori potrebbero essere mantenuti in alcuni attributi statici).
Dragan Marjanović il

8
Si noti che questo codice è concesso in licenza in GPL v3 che ha implicazioni per l'utilizzo nelle app di produzione.
TalkLittle

GPL e in base alla riflessione per chiamare metodi che potrebbero non essere presenti nelle future versioni di Android. Mhhh
Michel,

47

Il modo più semplice:

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

46

Per accedere all'altezza della barra di stato per dispositivi Android, preferiamo un modo programmatico per ottenerlo:

Codice di esempio

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

La variabile resultfornisce l'altezza nel pixel.

Per un rapido accesso

Inserisci qui la descrizione dell'immagine

Per ulteriori informazioni su altezza Title bar, Navigation bare Content View, sguardo gentilmente su Android schermo del dispositivo Taglie .


Proprio quello di cui avevo bisogno! getResources().getDisplayMetrics().heightPixels + resultfornisce l'altezza effettiva a schermo intero. Anche la risposta di Dragan Marjanović funziona, ma preferisco questa soluzione molto più breve e semplice.
Michel,

Questo approccio non è aggiornato a partire da Android Marshmallow. L'altezza della barra di stato può cambiare dal dispositivo o dalla versione Android. Uso migliore OnApplyWindowInsetsListener.
Heinrich,

32

Per prima cosa ottieni la vista (es. Per findViewById()) e poi puoi usare getWidth () sulla vista stessa.


3
Questo è in realtà il modo in cui la documentazione ti dice di farlo ... ma è un po 'inutile se NON stai usando una vista. potresti usare qualcos'altro, ad esempio mglsurfaceview.
gcb,

2
questo è meglio poiché la vista principale potrebbe non essere la dimensione del display. Ma assicurati che ciò avvenga in un punto in cui la vista di cui stai interrogando la dimensione è già stata disposta, che di solito non sarà all'interno di onCreate (). Puoi utilizzare un callback personalizzato da onWindowFocusChanged (hasFocus booleano) che verrà chiamato dopo che tutte le viste sono state misurate e così via, assicurandoti di non ricevere dimensioni errate per la vista che ti interessa ...
Dori

27

Ho due funzioni, una per l'invio del contesto e l'altra per ottenere altezza e larghezza in pixel:

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

e

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

È necessario aggiungere @SuppressLint("NewApi")appena sopra la firma della funzione per poter compilare.
Adil Malik,

Penso che sia meglio ottenere l'altezza e la larghezza in una volta piuttosto che in chiamate separate alle API perché altrimenti potrebbero non essere sincronizzati. Ciò potrebbe accadere se l'orientamento dello schermo cambia mentre il codice è in esecuzione.
Sam,

17

Per il ridimensionamento dinamico tramite XML esiste un attributo chiamato "android: layout_weight"

L'esempio seguente, modificato dalla risposta di Synic su questo thread , mostra un pulsante che occupa il 75% dello schermo (peso = 0,25) e una vista di testo che occupa il restante 25% dello schermo (peso = 0,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

Questo è il codice che uso per l'attività:

// `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();
}

Sembra abbastanza pulito e tuttavia, si prende cura della deprecazione.


17

Non è una soluzione molto migliore? DisplayMetrics viene fornito con tutto il necessario e funziona dall'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;
}

Puoi anche ottenere la visualizzazione effettiva (compresi i decori dello schermo, come la barra di stato o la barra di navigazione del software) usando getRealMetrics , ma funziona solo su 17+.

Mi sto perdendo qualcosa?


1
Non sottrae spazio per i controlli su schermo (come su tablet o dispositivi Nexus). Inoltre, ottengo un valore diverso (750 vs 800) sul mio tablet da 10 ", a seconda che l'attività sia attiva al termine del calcolo. Ma per i miei scopi, questo è più che soddisfacente. Grazie!
Steven L

15

Sto solo aggiungendo alla risposta di Francesco. L'altro osservatore più adatto, se si desidera scoprire la posizione nella finestra o la posizione nella schermata, è ViewTreeObserver.OnPreDrawListener ()

Questo può anche essere usato per trovare altri attributi di una vista che è per lo più sconosciuta al momento di onCreate () ad esempio la posizione di scorrimento, la posizione in scala.


15

Utilizzando il seguente codice in Attività.

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

15

Trova la larghezza e l'altezza dello schermo:

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

Usando questo, possiamo ottenere l'ultimo e sopra SDK 13.

// 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

Ho scoperto che questo ha funzionato.

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

5
Fantastico, ma questa è una cosa spaventosa di questo metodo nel codice sorgente: questo commento
Norbert,

12

Devo dire che se non ci sei Activity, ma in View(o hai una variabile di Viewtipo nel tuo ambito), non c'è bisogno di usare WINDOW_SERVICE. Quindi è possibile utilizzare almeno due modi.

Primo:

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

Secondo:

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

Tutti questi metodi che chiamiamo qui non sono deprecati.


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

Per ottenere le dimensioni dello schermo utilizzare metrices di visualizzazione

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

Ottieni l'altezza e la larghezza in pixel

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

9

Questa non è una risposta per l'OP, poiché voleva le dimensioni del display in pixel reali. Volevo le dimensioni in "pixel indipendenti dal dispositivo" e mettere insieme le risposte da qui https://stackoverflow.com/a/17880012/253938 e qui https://stackoverflow.com/a/6656774/253938 sono arrivato con questo:

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

9

Puoi ottenere la dimensione dell'altezza usando:

getResources().getDisplayMetrics().heightPixels;

e la dimensione della larghezza usando

getResources().getDisplayMetrics().widthPixels; 

8

Esiste un modo non deprecato per farlo utilizzando DisplayMetrics (API 1), che evita il disordine 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

Vorrei racchiudere il codice getSize in questo modo:

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

Questo si blocca su un emulatore con Android 4.0 (API 14).
JWW

6

Per chi è alla ricerca di dimensioni dello schermo utilizzabili senza barra di stato e barra delle azioni (anche grazie alla risposta di 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

Prima carica il file XML e poi scrivi questo codice:

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

Mostra larghezza e altezza in base alla risoluzione dello schermo.


6

Segui i metodi seguenti:

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

Ci sono momenti in cui è necessario conoscere le dimensioni precise dello spazio disponibile per un layout in OnCreate di un'attività. Dopo qualche pensiero ho scoperto questo modo di farlo.

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

Se per qualche motivo non vuoi aggiungere un'altra attività al manifest di Android, puoi farlo in questo modo:

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

Ovviamente, puoi anche restituire l'altezza nel pacchetto.
Steve Waring,

5

Se non desideri il sovraccarico di WindowManager, Punti o Display, puoi prendere gli attributi di altezza e larghezza dell'elemento Visualizza più in alto nel tuo XML, a condizione che la sua altezza e larghezza siano impostate su match_parent. (Questo è vero fino a quando il layout occupa l'intero schermo.)

Ad esempio, se il tuo XML inizia con qualcosa del genere:

<?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" >

Quindi findViewById(R.id.entireLayout).getWidth()restituirà la larghezza dello schermo e findViewById(R.id.entireLayout).getHeight()restituirà l'altezza dello schermo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.