Programowo ustaw wysokość w LayoutParams jako piksele niezależne od gęstości


123

Czy istnieje sposób, aby ustawić wysokość / szerokość LayoutParams jako piksele niezależne od gęstości (dp)? Wygląda na to, że wysokość / szerokość ustawione programowo są w pikselach, a nie w dp.

Odpowiedzi:


271

Musisz przeliczyć wartość spadku na piksele:

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

Dla mnie to załatwia sprawę.


10
Myślę, że getActivity (). GetResources (). GetDimension (resourceID) wykonują prawidłowe operacje konwersji.
StErMi

3
Działa dla mnie, ale różni się ... jeśli ustawię szerokość / wysokość ImageView za pomocą powyższej metody a używając XML. W XML ustawiłem 85dp, podczas gdy powyższa metoda wymaga "75", aby uzyskać ten sam rozmiar. Każdy pomysł, dlaczego?
Dirk

1
@Dirk Prawdopodobnie występuje problem z dopełnieniem / marginesem podczas ustawiania go programowo (zwykle musisz sam określić dopełnienie podczas ustawiania w kodzie). Nie powinno być żadnej różnicy między ustawieniem dp w XML lub w kodzie.
Tiago,

11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Wywołaj funkcję w ten sposób,

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

int heigh = getDPI(height or width, metrics);

To jest ... naprawdę złe. Masz zakodowane na stałe, aby obsługiwać tylko stałą liczbę gęstości. Jeśli chcesz skalować według współczynnika skalowania gęstości, po prostu pomnóż przez developer.android.com/reference/android/util/…, co również będzie takie samo jak zrobienie (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod

1
Tak, twoja nowa odpowiedź jest rozsądna. Lub, jak powiedziałem, po prostu pomnóż przez metryki. Gęstość. Po to jest.
hackbod

6

Ponieważ może być używany wielokrotnie:

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

Uważam, że bardziej praktyczne jest użycie współczynnika konwersji, ponieważ zwykle trzeba przeliczyć więcej niż jedną wartość. Ponieważ współczynnik konwersji się nie zmienia, oszczędza to trochę czasu przetwarzania.

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

Oto mój fragment:

public class DpiUtils {

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

}

gdzie DisplayMetrics metrics = getResources().getDisplayMetrics()


0

Odpowiedzi rozwiązanie nie zadziałało dla mnie, wysokość widoku była nadal wyłączona. Skończyło się na tym, co działa dobrze:

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

A jeśli chcesz na odwrót, piksele dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.