从 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_SP
、COMPLEX_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 尺寸的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在 Java 文档中指定应该从非 UI 线程调用方法
如何在 Spring/Spring Boot pom.xml 中指定 Java 版本?
在 PySpark Pandas UDF 中指定用户定义函数的正确方法