Програмно встановлена ​​висота на LayoutParams як пікселі, що не залежать від щільності


123

Чи є спосіб встановити висоту / ширину LayoutParams як пікселів, незалежних від щільності (dp)? Схоже, що висота / ширина, якщо встановлено програмно, знаходяться в пікселях, а не в dp.

Відповіді:


271

Вам потрібно перетворити значення dip в пікселі:

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

Для мене це робить трюк.


10
Я думаю, що getActivity (). GetResources (). GetDimension (resourceID) виконують правильні операції перетворення.
StErMi

3
Для мене працює, але він відрізняється ... якщо я встановити ширину / висоту ImageView, використовуючи метод, наведений вище, за допомогою xml. У XML я встановив 85dp, тоді як методу вище потрібно "75" для отримання однакового розміру. Будь-яка ідея чому?
Дірк

1
@Dirk Ви, мабуть, виникає проблема заміщення / маржинації, коли ви її встановлюєте програмно (зазвичай вам потрібно вказати прокладку самостійно, коли ви встановлюєте код). Не повинно бути різниці між встановленням dp у XML чи коді.
Тіаго

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/…, що також буде таким же, як і розмір * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT.
hackbod

1
Так, ваша нова відповідь розумна. Або, як я вже сказав, просто помножте на metrics.density. Саме це і є.
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);
}

А якщо ви хочете навпаки, пікселі до дп ...

protected float px2dp(float px){
    DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return Math.round(dp);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.