从Java代码中指定DIP尺寸的正确方法是什么?

52

我发现可以在XML布局中使用DIP来设置界面元素的尺寸,例如以下代码片段:

android:layout_width="10dip"

但所有的Java接口都需要以整数作为参数,而没有办法指定DIP中的尺寸。正确的计算方法是什么?

我想我必须使用DisplayMetrics类的密度属性,但这是正确的方式吗?

我可以依赖这个公式始终正确吗?

像素值 * DisplayMetrics.density = DIP

在Android中是否有用于转换的实用程序函数?

4个回答

92

有一个名为TypedValue.applyDimensions(int, float, DisplayMetrics)的实用方法可以完成此操作。

以下是如何使用它:

// returns the number of pixels for 123.4dip
int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
                     (float) 123.4, getResources().getDisplayMetrics());

在那个页面上,您可以找到一些其他类型,包括COMPLEX_UNIT_SPCOMPLEX_UNIT_PT。如果您不使用(int)强制转换,将得到浮点数。

我遇到了同样的问题,并通过查看代码找到了此解决方法。


12
这将像OP期望的那样,将像素转换为DIP而不是DIP转换为像素。当然,这也是我想要的。您可以使用以下代码实现:(int)(desiredDIP * context.getResources().getDisplayMetrics().density) - mxcl

46

那是正确的公式。虽然DisplayMetrics.density不是静态成员,所以根据你提到的同一文档,正确的用法是:

// Maybe store this in a static field?
final float SCALE = getContext().getResources().getDisplayMetrics().density;

// Convert dips to pixels
float valueDips = 16.0f;
int valuePixels = (int)(valueDips * SCALE + 0.5f); // 0.5f for rounding

1
谢谢Roman,我不知道这一部分。还有两个额外的与主题相关的问题:-密度在两个维度上总是相等的吗?看起来是这样(因为这只是一个值),但也许有其他公式可以计算这个值。-没有API可以帮我进行转换吗?我真的必须在我的代码中编写以下代码吗?在XML布局代码中,可以将“dip”指定为单位,为什么在Java API中不可能呢? - Pavel Lahoda
1
我认为你可以安全地假设两个维度的密度相等。请记住,DisplayMetrics.density是逻辑密度,而不是实际屏幕密度(实际屏幕密度可能略有不同于逻辑密度)。关于转换API,编写一个帮助方法(例如Util.dip)将dip转换为像素以供函数调用非常简单。无论如何,用Java处理单位更加清晰。 - Roman Nurik

9
使用显示度量密度字段,您可以获得一个缩放因子来转换dip。使用Math.round方法将浮点数转换为整数,无需进行强制转换或添加0.5。
// Converting dips to pixels
float dips = 20.0f;
float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = Math.round(dips * scale);

// Converting pixels to dips
int pixels = 15;
float scale = getContext().getResources().getDisplayMetrics().density;
float dips = pixels / scale;

Math.round确实进行了转换。(int)Math.floor(a + 0.5f)就是Math.round在底层所做的事情。 - Christopher Perry

5

我认为最好的方法不是在代码中定义任何尺寸,而是使用values/dimens.xml文件。您可以始终以所需单位定义自己的尺寸,例如:

<dimen name="my_layout_height">120dp</dimen>

然后在Activity中引用它,像这样:

getResources().getDimensions(R.dimen.my_layout_height);

这将在进行必要的转换后返回像素。当然,您也可以在其他XML中引用它,如下所示:
android:layout_width="@dimen/my_layout_height"

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