Réglage de la hauteur par programme sur LayoutParams comme pixels indépendants de la densité

123

Existe-t-il un moyen de définir la hauteur / largeur d'un LayoutParams en tant que pixels indépendants de la densité (dp)? Il semble que la hauteur / largeur, lorsqu'elle est définie par programme, est en pixels et non en dp.

psychotik
la source

Réponses:

271

Vous devez convertir votre valeur de creux en pixels:

int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, <HEIGHT>, getResources().getDisplayMetrics());

Pour moi, cela fait l'affaire.

Mokus
la source
10
Je pense que getActivity (). GetResources (). GetDimension (resourceID) effectue les opérations de conversion correctes.
StErMi
3
Fonctionne pour moi, mais cela diffère ... si je définis la largeur / hauteur d'un ImageView en utilisant la méthode ci-dessus par rapport à l'utilisation du xml. Dans le XML, j'ai mis 85dp alors que la méthode ci-dessus a besoin de "75" pour produire la même taille. Une idée pourquoi?
Dirk le
1
@Dirk Il y a probablement un problème de remplissage / marge lorsque vous le définissez par programme (vous devez généralement spécifier le remplissage vous-même lorsque vous le définissez dans le code). Il ne devrait y avoir aucune différence entre la définition de dp en XML ou en code.
Tiago
11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Appelez la fonction comme ceci,

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

int heigh = getDPI(height or width, metrics);
Enfers
la source
C'est ... vraiment faux. Vous avez codé en dur pour ne prendre en charge qu'un nombre fixe de densités. Si vous souhaitez mettre à l'échelle par le facteur de mise à l'échelle de la densité, multipliez simplement par developer.android.com/reference/android/util/... ce qui équivaudrait également à faire (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod
1
Oui, votre nouvelle réponse est raisonnable. Ou comme je l'ai dit, multipliez simplement par la densité métrique. C'est à cela que ça sert.
hackbod
6

Puisqu'il peut être utilisé plusieurs fois:

public static int convDpToPx(Context context, float dp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
}

J'ai trouvé plus pratique d'utiliser le taux de conversion, car il faut généralement convertir plus d'une valeur. Étant donné que le taux de conversion ne change pas, cela économise un peu de temps de traitement.

/**
 * Get conversion rate from dp into px.<br>
 * E.g. to convert 100dp: px = (int) (100 * convRate);
 * @param context e.g. activity
 * @return conversion rate
 */
public static float convRateDpToPx(Context context) {
    return context.getResources().getDisplayMetrics().densityDpi / 160f;
}
Gunnar Bernstein
la source
5

Voici mon extrait:

public class DpiUtils {

    public static int toPixels(int dp, DisplayMetrics metrics) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
    }

}

DisplayMetrics metrics = getResources().getDisplayMetrics()

romain
la source
0

La solution répondue n'a pas fonctionné pour moi, la hauteur de la vue était toujours désactivée. J'ai fini avec ceci, qui fonctionne bien:

protected int dp2px(int dp){
    final float scale = getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
}

Et si vous voulez l'inverse, les pixels à dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Monsieur L
la source