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

#android #android-layout

#Android #android-layout

Вопрос:

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

Ответ №1:

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

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

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

Комментарии:

1. Я думаю, что getActivity().getResources().getDimension(resourceId) выполняет правильные операции преобразования.

2. У меня работает, но это отличается… если я установлю ширину / высоту ImageView, используя метод, описанный выше, по сравнению с использованием xml. В XML я установил 85dp, в то время как описанному выше методу требуется «75» для получения того же размера. Есть идеи, почему?

3. @Dirk Вероятно, при программной настройке возникает проблема с заполнением / полями (обычно вам приходится указывать заполнение самостоятельно при установке в коде). Не должно быть никакой разницы между настройкой dp в XML или в коде.

Ответ №2:

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

Комментарии:

1. То есть… действительно неправильно. Вы жестко запрограммировали поддержку только фиксированного количества плотностей. Если вы хотите масштабировать по коэффициенту масштабирования плотности, просто умножьте на developer.android.com/reference/android/util/… что также было бы таким же, как выполнение (size * metrics.densityDpi) / DisplayMetrics. DENSITY_DEFAULT.

2. Да, ваш новый ответ является разумным. Или, как я уже сказал, просто умножьте на metrics.density. Вот для чего это нужно.

Ответ №3:

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

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

Ответ №4:

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

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

Ответ №5:

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

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