以密度无关像素为单位通过编程在LayoutParams上设置高度

127

有没有办法以密度无关像素(dp)的形式设置LayoutParams的高度/宽度?看起来,当以编程方式设置高度/宽度时,它们是以像素而不是dp为单位的。

5个回答

275

你需要将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" 才能产生相同的大小。有什么想法为什么会这样? - Dirk
1
@Dirk 当你在程序中设置时,可能存在填充/边距问题(通常在代码中设置时必须自己指定填充)。在XML或代码中设置dp应该没有任何区别。 - Bitcoin Cash - ADA enthusiast

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

这真的是非常错误的。你已经硬编码只支持固定数量的密度。如果你想按密度缩放因子进行缩放,只需乘以http://developer.android.com/reference/android/util/DisplayMetrics.html#density,这也相当于执行(size * metrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT。 - hackbod
1
是的,你的新答案很合理。或者就像我说的那样,只需乘以metrics.density。这就是它的作用。 - hackbod

7

由于它可能被多次使用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接