Comment déterminer la largeur de l'écran en termes de dp ou de dip lors de l'exécution dans Android?


193

J'ai besoin de coder la disposition des widgets Android en utilisant dip / dp (dans les fichiers java). Au moment de l'exécution si je code

int pixel=this.getWindowManager().getDefaultDisplay().getWidth(),;

cela renvoie la largeur de l'écran en pixels (px). Pour convertir cela en dp, j'ai codé:

int dp =pixel/(int)getResources().getDisplayMetrics().density ;

cela ne semble pas renvoyer la bonne réponse. J'ai fait l'émulateur de WVGA800 dont la résolution d'écran est de 480 par 800. Lorsque vous exécutez l'émulateur et laissez le code imprimer les valeurs de pixel et de dp, il est venu à 320 dans les deux. Cet émulateur est de 240 dpi dont le facteur d'échelle serait de 0,75.

Réponses:


377

Essaye ça

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);

float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;

OU

Merci @ Tomáš Hubálek

DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();    
float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

91
Pourquoi est-il nécessaire d'appeler WindowManager? Et ce code? DisplayMetrics displayMetrics = resources.getDisplayMetrics (); float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
Tomáš Hubálek

2
Cela n'a pas fonctionné pour moi en utilisant un écran à très haute densité. C'était comme si elle n'obtenait qu'une petite partie de l'écran. Cette solution a fonctionné pour moi: stackoverflow.com/a/18712361/956975 Display display = getWindowManager (). GetDefaultDisplay (); Taille du point = nouveau Point (); display.getSize (taille); int largeur = taille.x; int hauteur = size.y;
marienke

1
@dsdsdsdsd: context est n'importe quelle instance de la classe Context. Plus particulièrement, l'activité est une sous-classe de contexte (utilisez-la donc dans une activité et getActivity () dans un fragment). L'application et le service sont également des sous-classes de contexte.
François POYER

112

Je suis tombé sur cette question de Google, et plus tard j'ai trouvé une solution simple valable pour l'API> = 13.

Pour de futures références:

Configuration configuration = yourActivity.getResources().getConfiguration();
int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.
int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

Voir Référence de classe de configuration

Edit: Comme l'a noté Nick Baicoianu, cela renvoie la largeur / hauteur utilisable de l'écran (qui devrait être intéressante dans la plupart des utilisations). Si vous avez besoin des dimensions d'affichage réelles , respectez la première réponse.


23
Une différence importante entre l'utilisation de screenWidthDp / screenHeightDp de Configuration par rapport à DisplayMetrics widthPixels / heightPixels est que Configuration renvoie les dimensions d'affichage utilisables (moins la barre d'état, etc.), tandis que DisplayMetrics renvoie les dimensions plein écran.
Nick Baicoianu

Ceci est seulement pour l' API de niveau 13 et jusqu'à
ono

Pour ajouter au commentaire de @ NickBaicoianu, les méthodes getConfiguration () et getDisplayMetrics () fonctionnent en mode multi-fenêtres. c'est-à-dire que les tailles reflètent celle de la fenêtre, pas celle de l'écran.
nmw

7

Il vous manque une valeur de densité par défaut de 160.

    2 px = 3 dip if dpi == 80(ldpi), 320x240 screen
    1 px = 1 dip if dpi == 160(mdpi), 480x320 screen
    3 px = 2 dip if dpi == 240(hdpi), 840x480 screen

En d'autres termes, si vous concevez votre mise en page avec une largeur égale à 160 dip en mode portrait, ce sera la moitié de l'écran sur tous les appareils ldpi / mdpi / hdpi (sauf les tablettes, je pense)


Ce à quoi vous avez répondu est le raisonnement logique derrière ma question. Je comprends ça. Comment dois-je coder cela en java pour qu'au moment de l'exécution quelle que soit la résolution de l'écran, la largeur de dpi correcte soit choisie par le code?
Khushboo

J'espère que je vais bien cette fois :) Utilisation DisplayMetrics outMetrics = null; getWindowManager().getDefaultDisplay().getMetrics(outMetrics);dans l'activité. Ensuite, outMetrics.densityvous donnera le facteur d'échelle de l'appareil actuel, comme indiqué dans la documentation
Mykhailo Gaidai

6

Que diriez-vous d'utiliser à la place?

final DisplayMetrics displayMetrics=getResources().getDisplayMetrics();
final float screenWidthInDp=displayMetrics.widthPixels/displayMetrics.density;
final float screenHeightInDp=displayMetrics.heightPixels/displayMetrics.density;

6
DisplayMetrics displayMetrics = new DisplayMetrics();

getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);

int width_px = Resources.getSystem().getDisplayMetrics().widthPixels;

int height_px =Resources.getSystem().getDisplayMetrics().heightPixels;

int pixeldpi = Resources.getSystem().getDisplayMetrics().densityDpi;


int width_dp = (width_px/pixeldpi)*160;
int height_dp = (height_px/pixeldpi)*160;

8
Pensez à donner quelques explications
bigbounty

5

Réponse en kotlin:

  context?.let {
        val displayMetrics = it.resources.displayMetrics
        val dpHeight = displayMetrics.heightPixels / displayMetrics.density
        val dpWidth = displayMetrics.widthPixels / displayMetrics.density
    }

4

Simplifié pour Kotlin:

val widthDp = resources.displayMetrics.run { widthPixels / density }
val heightDp = resources.displayMetrics.run { heightPixels / density }

2

Obtenez la largeur et la hauteur de l'écran en termes de DP avec une bonne décoration:

Étape 1: créer une interface

public interface ScreenInterface {

   float getWidth();

   float getHeight();

}

Étape 2: créer une classe d'implémenteur

public class Screen implements ScreenInterface {
    private Activity activity;

    public Screen(Activity activity) {
        this.activity = activity;
    }

    private DisplayMetrics getScreenDimension(Activity activity) {
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics;
    }

    private float getScreenDensity(Activity activity) {
        return activity.getResources().getDisplayMetrics().density;
    }

    @Override
    public float getWidth() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.widthPixels / getScreenDensity(activity);
    }

    @Override
    public float getHeight() {
        DisplayMetrics displayMetrics = getScreenDimension(activity);
        return displayMetrics.heightPixels / getScreenDensity(activity);
    }
} 

Étape 3: Obtenez la largeur et la hauteur de l'activité:

Screen screen = new Screen(this); // Setting Screen
screen.getWidth();
screen.getHeight();

Est-ce que cela renvoie la hauteur et la largeur en pixels ou en dp?
Taslim Oseni

comme appelé .densité c'est pourquoi son vous donne en dp
Ali Azaz Alam

Je ne pense pas que ce soit une bonne idée d'ajouter des tonnes de code à votre application pour résoudre une tâche simple
Ruslan Berozov

Monsieur, c'est à vous de mettre en œuvre la classe ou de la coder directement. De la classe définie, vous pouvez facilement extraire le code pour une implémentation directe.
Ali Azaz Alam

0

Si vous voulez simplement connaître la largeur de votre écran, vous pouvez simplement rechercher la "plus petite largeur d'écran" dans vos options de développement. Vous pouvez même le modifier.


0

Essaye ça:

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

-5

Votre problème est de lancer le flotteur à un entier, perdant ainsi sa précision. Vous devez également multiplier par le facteur et non pas diviser.

Faites ceci:

int dp = (int)(pixel*getResources().getDisplayMetrics().density);

3
Cette réponse est incorrecte. Sur developer.android.com/guide/practices/… , Pixel = Dp * Densité.
Vance-Turner
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.