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

Posted

技术标签:

【中文标题】从 Java 代码中指定 DIP 尺寸的正确方法是啥?【英文标题】:What is the correct way to specify dimensions in DIP from Java code?从 Java 代码中指定 DIP 尺寸的正确方法是什么? 【发布时间】:2011-01-15 09:11:51 【问题描述】:

我发现可以使用 DIP 在 XML 布局中设置界面元素的尺寸,如下所示:

android:layout_

但所有 Java 接口都将整数作为参数,并且无法在 DIP 中指定维度。计算这个的正确方法是什么?

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

我可以相信这个公式总是正确的吗?

像素 * DisplayMetrics.density = dip

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

【问题讨论】:

【参考方案1】:

有一个名为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) 类型转换,您将获得浮点数。

我也遇到了同样的问题,我翻了一下代码发现了这个问题。

【讨论】:

这会将像素转换为 DIP 而不是 DIP 转换为像素,我相信这是 OP 想要的。这当然是我想要的。你喜欢哪个:(int)(desiredDIP * context.getResources().getDisplayMetrics().density)【参考方案2】:

那是正确的公式。虽然DisplayMetrics.density不是静态成员,所以根据same document you alluded to,正确用法是:

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

【讨论】:

感谢 Roman,我不知何故忽略了这部分。还有两个额外的与主题相关的问题: - 两个维度的密度是否总是相等的?看起来是这样(因为这只是一个值),但也许还有其他一些公式可以计算这个值。 - 没有任何 API 可以为我进行转换吗?我真的必须在我的代码中编写以下代码吗?在 XML 布局代码中,可以指定“dip”为单位,为什么在 Java API 中不能? 我认为你可以放心地假设密度在两个维度上是相等的。请记住,DisplayMetrics.density 是逻辑密度,而不是实际屏幕密度(可能与逻辑密度略有不同)。关于转换 API,编写一个帮助方法(例如 Util.dip)将倾角转换为像素以用于函数调用是很简单的。无论如何,以这种方式处理 Java 中的单元会更干净。【参考方案3】:

使用显示指标密度字段,您可以获得一个比例因子来转换为/从下降。使用 Math.round 方法将浮点数转换为 int,无需强制转换或添加 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 在幕后所做的。【参考方案4】:

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

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

然后在您的活动中引用此内容,例如:

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

这将在进行必要的转换后返回 像素。当然,您也可以在其他 XML 中引用它,例如:

android:layout_

【讨论】:

以上是关于从 Java 代码中指定 DIP 尺寸的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 sqoop 中指定多个泛型参数的正确方法是啥

有没有办法在 Java 文档中指定应该从非 UI 线程调用方法

如何在 Spring/Spring Boot pom.xml 中指定 Java 版本?

在 PySpark Pandas UDF 中指定用户定义函数的正确方法

在 Pagelines Pro Wordpress 主题中指定 <img> 的图像尺寸

如何在Kotlin中指定递归泛型参数?