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.

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.


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);

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;
}

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()


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);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.