Formule px à dp, dp à px android

j'essaie de calculer une quantité variable de pixels aux pixels indépendants de la densité et vice-versa.

cette formule (px to dp): dp = (int)(px / (displayMetrics.densityDpi / 160)); ne fonctionne pas sur les petits appareils parce qu'elle est divisée par zéro.

C'est ma formule dp à px:

px = (int)(dp * (displayMetrics.densityDpi / 160));

quelqu'un Pourrait-il me donner quelques conseils?

137
demandé sur Bram 2011-11-29 14:38:16

18 réponses

Note: la solution largement utilisée ci-dessus est basée sur displayMetrics.density . Cependant, les docs expliquer que cette valeur est une valeur arrondie, utilisé avec l'écran des compartiments. Par exemple. sur mon Nexus 10, il retourne 2, où la valeur réelle serait 298dpi (réel) / 160dpi (par défaut) = 1.8625.

selon vos besoins, vous pourriez avoir besoin de la transformation exacte, qui peut être réalisée comme ceci:

[Edit] ce n'est pas destiné à être mélangé avec Android unité dp interne, car cela est bien sûr toujours basé sur les seaux d'écran. Utilisez ceci lorsque vous voulez une unité qui devrait rendre la même taille réelle sur des appareils différents.

convertir dp en pixel:

public int dpToPx(int dp) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));     
}

convertir pixel en dp:

public int pxToDp(int px) {
    DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
    return Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}

notez qu'il y a des propriétés xdpi et ydpi, vous pourriez vouloir les distinguer, mais je ne peux pas imaginer un affichage sain où ces valeurs diffèrent grandement.

304
répondu Bachi 2016-12-09 20:18:50

j'ai résolu mon problème en utilisant les formules suivantes. Peuvent l'être d'autres personnes d'en profiter.

dp px:

displayMetrics = context.getResources().getDisplayMetrics();
return (int)((dp * displayMetrics.density) + 0.5);

px pour dp:

displayMetrics = context.getResources().getDisplayMetrics();
return (int) ((px/displayMetrics.density)+0.5);
99
répondu Bram 2016-03-24 07:38:55

px pour dp:

int valueInpx = ...;
int valueInDp= (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources()
                .getDisplayMetrics());
30
répondu Ian 2011-11-29 11:08:28

il suffit d'appeler getResources().getDimensionPixelSize(R.dimen.your_dimension) pour convertir de dp unités en pixels

25
répondu pelotasplus 2015-04-11 00:41:57

moyen Efficace jamais

DP de Pixel:

private int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

Pixel à DP:

private int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

espérons que cela vous aidera.

22
répondu Hiren Patel 2016-04-07 03:54:36

utilisez cette fonction

private int dp2px(int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
14
répondu Prashant Maheshwari Andro 2015-06-19 09:24:53
px = dp * (dpi / 160)

dp = px * (160 / dpi)
5
répondu ct_rob 2011-11-29 10:54:50

dans la plupart des cas, les fonctions de conversion sont appelées fréquemment. Nous pouvons l'optimiser en ajoutant la memoization. Donc,il ne calcule pas chaque fois que la fonction est appelée.

déclarons un HashMap qui stockera les valeurs calculées.

private static Map<Float, Float> pxCache = new HashMap<>();

une fonction qui calcule les valeurs en pixels:

public static float calculateDpToPixel(float dp, Context context) {

        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        float px = dp * (metrics.densityDpi / 160f);
        return px;

    }

une fonction de mémoization qui renvoie la valeur de HashMap et maintient l'enregistrement de la précédente valeur.

La Memoization

peut être implémentée de différentes façons en Java. Pour Java 7 :

public static float convertDpToPixel(float dp, final Context context) {

        Float f = pxCache.get(dp);
        if (f == null) {
            synchronized (pxCache) {
                f = calculateDpToPixel(dp, context);
                pxCache.put(dp, f);
            }

        }

        return f;
    }

Java 8 supporte la fonction Lambda :

public static float convertDpToPixel(float dp, final Context context) {

        pxCache.computeIfAbsent(dp, y ->calculateDpToPixel(dp,context));
}

Merci.

3
répondu Parth mehta 2015-02-26 06:52:32
2
répondu KMI 2011-11-29 12:46:43

ci-dessous les fonctions ont bien fonctionné pour moi à travers les appareils.

il est tiré de https://gist.github.com/laaptu/7867851

public static float convertPixelsToDp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}

public static float convertDpToPixel(float dp){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}
2
répondu Blesson Jose 2015-11-13 05:16:44

// pour obtenir en termes de Décimal/Float

public static float convertPixelsToDp(float px, Context context) {

    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}



public static float convertDpToPixel(float dp, Context context) {
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}


// for  getting in terms of Integer

private int convertPxToDp(int px, Context context) {
    Resources resources = context.getResources();
    return Math.round(px / (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
}


private int convertDpToPx(int dp, Context context) {
    Resources resources = context.getResources();

    return Math.round(dp * (resources.getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));

}

________________________________________________________________________________

public static float convertPixelsToDp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}

public static float convertDpToPixel(float dp){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float px = dp * (metrics.densityDpi / 160f);
    return Math.round(px);
}


private int convertDpToPx(int dp){
    return Math.round(dp*(getResources().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));

}

private int convertPxToDp(int px){
    return Math.round(px/(Resources.getSystem().getDisplayMetrics().xdpi/DisplayMetrics.DENSITY_DEFAULT));
}
2
répondu TRINADH KOYA 2016-09-21 12:08:00

si vous êtes à la recherche d'une calculatrice en ligne pour convertir DP, SP, pouces, millimètres, points ou pixels les uns aux autres à des densités d'écran différentes, c'est l'outil le plus complet que je connaisse de .

1
répondu Paul Lammertsma 2014-06-11 10:08:03

vous pouvez utiliser [DisplayMatrics][1] et déterminer la densité de l'écran. Quelque chose comme ceci:

int pixelsValue = 5; // margin in pixels
float d = context.getResources().getDisplayMetrics().density;
int margin = (int)(pixelsValue * d);

comme je m'en souviens, il est préférable d'utiliser les planchers pour les décalages et les arrondis pour les largeurs.

0
répondu Houcine 2011-11-29 11:00:07

N'hésitez pas à utiliser cette méthode j'ai écrit:

int dpToPx(int dp)
{
    return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
0
répondu Ben Kane 2013-07-10 22:02:25

la réponse acceptée ci-dessus n'est pas entièrement exacte. Selon les informations obtenues en inspectant le code source Android:

Resources.getDimension() et getDimensionPixelOffset() / getDimensionPixelSize() diffèrent seulement en ce que la première renvoie float tandis que les deux derniers renvoient la même valeur arrondie à int appropriatelly. Pour chacun d'eux, la valeur de retour est en pixels bruts.

les trois fonctions sont mises en œuvre en appelant Resources.getValue() et conversion ainsi obtenue TypedValue en appelant respectivement TypedValue.complexToDimension() , TypedValue.complexToDimensionPixelOffset() et TypedValue.complexToDimensionPixelSize() .

par conséquent, si vous voulez obtenir la valeur" raw "avec L'unité spécifiée dans XML source, appelez Resources.getValue() et utilisez les méthodes de la classe TypedValue .

0
répondu Jaromír Adamec 2014-09-01 16:01:48

DisplayMetrics displayMetrics = contaxt.getResources() .getDisplayMetrics ();

    int densityDpi = (int) (displayMetrics.density * 160f);
    int ratio = (densityDpi / DisplayMetrics.DENSITY_DEFAULT);
    int px;
    if (ratio == 0) {
        px = dp;
    } else {
        px = Math.round(dp * ratio);

    }
0
répondu Sushil Mittal 2014-09-17 10:24:12

variation sur ct_robs réponse ci-dessus, si vous utilisez des entiers, qui non seulement évite de diviser par 0, Il produit également un résultat utilisable sur les petits appareils:

dans les Calculs entiers impliquant une division pour la plus grande précision, multiplier d'abord avant de diviser pour réduire les effets de troncature.

px = dp * dpi / 160 dp = px * 160 / ppp

5 * 120 = 600 / 160 = 3

au lieu de

5 * (120 / 160 = 0) = 0

si vous voulez un résultat arrondi faire

px = (10 * dp * dpi / 160 + 5) / 10 dp = (10 * px * 160 / dpi + 5) / 10

10 * 5 * 120 = 6000 / 160 = 37 + 5 = 42 / 10 = 4

0
répondu user2624395 2015-01-31 22:52:20

avec l'aide d'autres réponses que j'ai écrit cette fonction.

public static int convertToPixels(Context context, int nDP)
{
        final float conversionScale = context.getResources().getDisplayMetrics().density; 
        return (int) ((nDP * conversionScale) + 0.5f) ;
}
0
répondu Abhishek 2016-01-05 05:36:24