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?
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.
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);
px pour dp:
int valueInpx = ...;
int valueInDp= (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, valueInpx , getResources()
.getDisplayMetrics());
il suffit d'appeler getResources().getDimensionPixelSize(R.dimen.your_dimension)
pour convertir de dp
unités en pixels
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.
utilisez cette fonction
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
}
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 Memoizationpeut ê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.
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);
}
// 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));
}
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 .
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.
N'hésitez pas à utiliser cette méthode j'ai écrit:
int dpToPx(int dp)
{
return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
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
.
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);
}
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
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) ;
}