Establezca programáticamente la altura en LayoutParams como píxeles independientes de la densidad

123

¿Hay alguna forma de establecer el alto / ancho de un LayoutParams como píxeles independientes de la densidad (dp)? Parece que la altura / anchura, cuando se establece mediante programación, están en píxeles y no en dp.

psicotik
fuente

Respuestas:

271

Necesita convertir su valor de inmersión en píxeles:

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

Para mí este es el truco.

Mokus
fuente
10
Creo que getActivity (). GetResources (). GetDimension (resourceID) realiza las operaciones de conversión correctas.
StErMi
3
Funciona para mí, pero difiere ... si configuro el ancho / alto de un ImageView usando el método anterior en lugar de usar el xml. En el XML configuré 85dp, mientras que el método anterior necesita "75" para producir el mismo tamaño. ¿Alguna idea de por qué?
Dirk
1
@Dirk Probablemente haya un problema de relleno / margen cuando lo configura mediante programación (generalmente debe especificar el relleno usted mismo cuando configura el código). No debería haber ninguna diferencia entre configurar dp en XML o en código.
Tiago
11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Llama a la función así,

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

int heigh = getDPI(height or width, metrics);
infierno
fuente
Eso está ... realmente mal. Ha codificado para admitir solo un número fijo de densidades. Si desea escalar por el factor de escala de densidad, simplemente multiplique por developer.android.com/reference/android/util/… que también sería lo mismo que hacer (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
Hackbod
1
Sí, su nueva respuesta es razonable. O como dije, simplemente multiplique por metrics.density. Esto es para lo que sirve.
Hackbod
6

Como se puede usar varias veces:

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

Me resultó más práctico utilizar la tasa de conversión, ya que habitualmente se debe convertir más de un valor. Como la tasa de conversión no cambia, ahorra un poco de tiempo de procesamiento.

/**
 * 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
fuente
5

Aquí está mi fragmento:

public class DpiUtils {

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

}

dónde DisplayMetrics metrics = getResources().getDisplayMetrics()

romano
fuente
0

La solución respondida no funcionó para mí, la altura de la vista todavía estaba apagada. Terminé con esto, que funciona bien:

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

Y si quieres al revés, los píxeles dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Señor l
fuente