Программно установить высоту LayoutParams как пиксели, не зависящие от плотности

123

Есть ли способ установить высоту / ширину LayoutParams как независимые от плотности пиксели (dp)? Похоже, что высота / ширина, если они установлены программно, находятся в пикселях, а не в dp.

psychotik
источник

Ответы:

271

Вам нужно преобразовать значение падения в пиксели:

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

Для меня это главное.

Mokus
источник
10
Я думаю, что getActivity (). GetResources (). GetDimension (resourceID) выполняет правильные операции преобразования.
StErMi
3
Работает для меня, но отличается ... если я устанавливаю ширину / высоту ImageView, используя метод выше, по сравнению с использованием xml. В XML я установил 85dp, тогда как описанному выше методу требуется «75» для получения того же размера. Есть идеи, почему?
Дирк
1
@Dirk Вероятно, возникает проблема с заполнением / полем, когда вы устанавливаете его программно (обычно вам нужно указать заполнение самостоятельно, когда вы устанавливаете код). Не должно быть никакой разницы между установкой dp в XML или в коде.
Tiago
11
 public static int getDPI(int size, DisplayMetrics metrics){
     return (size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;        
 }

Вызовите функцию следующим образом:

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

int heigh = getDPI(height or width, metrics);
Аид
источник
Это ... действительно неправильно. Вы жестко запрограммировали поддержку только фиксированного количества плотностей. Если вы хотите масштабировать по коэффициенту масштабирования плотности, просто умножьте его на developer.android.com/reference/android/util/…, что также будет таким же, как при выполнении (size * metrics.de densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod
1
Да, ваш новый ответ разумен. Или, как я уже сказал, просто умножьте на метрику. Плотность. Вот для чего это нужно.
hackbod
6

Поскольку его можно использовать несколько раз:

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

Я счел более практичным использовать коэффициент конверсии, поскольку обычно необходимо преобразовать более одного значения. Поскольку коэффициент конверсии не меняется, это немного экономит время обработки.

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

Вот мой фрагмент:

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

Римский
источник
0

Ответное решение у меня не сработало, высота обзора все еще была отключена. В итоге я получил это, что хорошо работает:

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

А если хотите наоборот, пиксели в dp ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Г-н Л
источник