Legen Sie die Höhe von LayoutParams programmgesteuert als dichteunabhängige Pixel fest

123

Gibt es eine Möglichkeit, die Höhe / Breite eines LayoutParams als dichteunabhängige Pixel (dp) festzulegen ? Es sieht so aus, als ob die Höhe / Breite, wenn sie programmgesteuert eingestellt wird, in Pixel und nicht in dp angegeben ist.

Psychotik
quelle

Antworten:

271

Sie müssen Ihren Dip-Wert in Pixel konvertieren:

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

Für mich ist das der Trick.

Mokus
quelle
10
Ich denke, dass getActivity (). GetResources (). GetDimension (resourceID) die richtigen Konvertierungsvorgänge ausführt.
StErMi
3
Funktioniert für mich, aber es unterscheidet sich ... wenn ich die Breite / Höhe einer ImageView mit der oben beschriebenen Methode oder mit der XML-Methode einstelle. Im XML habe ich 85dp eingestellt, während die obige Methode "75" benötigt, um die gleiche Größe zu erzeugen. Irgendeine Idee warum?
Dirk
1
@Dirk Es gibt wahrscheinlich ein Auffüll- / Randproblem, wenn Sie es programmgesteuert festlegen (normalerweise müssen Sie das Auffüllen selbst angeben, wenn Sie Code festlegen). Es sollte keinen Unterschied zwischen der Einstellung von dp in XML oder im Code geben.
Tiago
11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Rufen Sie die Funktion so auf:

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

int heigh = getDPI(height or width, metrics);
Hades
quelle
Das ist ... wirklich falsch. Sie haben fest codiert, um nur eine feste Anzahl von Dichten zu unterstützen. Wenn Sie von der Dichte Skalierungsfaktor skalieren möchten, nur multiplizieren mit developer.android.com/reference/android/util/... , die wäre auch die gleiche wie zu tun (Größe * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
Hackbod
1
Ja, Ihre neue Antwort ist vernünftig. Oder wie gesagt, multiplizieren Sie einfach mit der Metrik. Dafür ist es da.
Hackbod
6

Da es mehrfach verwendet werden kann:

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

Ich fand es praktischer, die Conversion-Rate zu verwenden, da normalerweise mehr als ein Wert konvertiert werden muss. Da sich die Conversion-Rate nicht ändert, spart dies etwas Verarbeitungszeit.

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

Hier ist mein Ausschnitt:

public class DpiUtils {

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

}

wo DisplayMetrics metrics = getResources().getDisplayMetrics()

römisch
quelle
0

Die beantwortete Lösung funktionierte bei mir nicht, die Höhe der Ansicht war immer noch ausgeschaltet. Am Ende hatte ich das, was gut funktioniert:

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

Und wenn Sie umgekehrt wollen, Pixel zu dp ...

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