Android并以dp为单位以编程方式设置宽度和高度

SK9*_*SK9 292 scaling android

我正在做:

button.setLayoutParams(new GridView.LayoutParams(65, 65));

根据文档,宽度和高度的单位(上面都是65)是"像素".你如何强制这是设备无关的像素,或"dp"?

Rob*_*ond 529

您必须使用显示比例因子将其从dps转换为像素.

final float scale = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scale + 0.5f);
Run Code Online (Sandbox Code Playgroud)

  • 正确的转换是(int)(dps*scale + 0.5f).这是我们在整个框架中使用的公式. (107认同)
  • @RomainGuy,您可以在API中添加一个实用程序函数,将`dp`转换为`px`吗?谢谢. (32认同)
  • 公式在文档中.如需进一步阅读,请访问http://developer.android.com/guide/practices/screens_support.html#screen-independence的第3部分. (8认同)
  • The "dps" variable is the input value that you want to convert. (4认同)
  • 这里的dps是什么?我得到"dps无法解析为变量"错误?什么类型的"dps"需要声明? (3认同)
  • 关于`+0.5f`,目的是四舍五入到最近的像素。如果不考虑,像素数将始终向下舍入,因为转换为 `int` 会截断/降低输入。这里有一些例子来说明这一点:`round(3) = floor(3 + .5) = floor(3.5) = 3`,`round(2.5) = floor(2.5 + .5) = floor(3) = 3 `, `round(2.49) = floor(2.49 + .5) = floor(2.99) = 2` (2认同)

drs*_*boo 215

我知道这是一个老问题但是我发现了一种更简洁的方式来进行这种转换.

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, getResources().getDisplayMetrics());
Run Code Online (Sandbox Code Playgroud)

  • 找不到如何做到这一点做得好.我不喜欢在几个地方重复一个公式!谢谢. (7认同)
  • 这应该是可以接受的答案,而不是当前这个数字(0.5)从无处可见的神奇的答案 (7认同)
  • 如果没有,则使用公式创建函数 (2认同)
  • @Johny19 0.5 不是魔术。这只是如何将浮点数四舍五入到最接近的整数而不是截断它。有关更多详细信息,请参阅我对 Robby Pond 的回答的评论。 (2认同)

vin*_*'th 35

根据您的要求,还有其他解决方案.您似乎在编译时知道dp中的维度,因此您可以在资源中添加维度条目.然后你可以查询dimen条目,它将自动转换为此调用中的像素:

final float inPixels= mActivity.getResources().getDimension(R.dimen.dimen_entry_in_dp);
Run Code Online (Sandbox Code Playgroud)

而您的dimens.xml将具有:

<dimen name="dimen_entry_in_dp">72dp</dimen>
Run Code Online (Sandbox Code Playgroud)

扩展这个想法,你可以简单地存储1dp或1sp的值作为维度条目并查询该值并将其用作乘数.使用此方法,您将使代码与数学内容隔离,并依赖库来执行计算.


Dav*_*vid 34

测试的最简单方法(甚至可以从api 1开始):

getResources().getDimensionPixelSize(R.dimen.example_dimen);
Run Code Online (Sandbox Code Playgroud)

来自文件:

检索特定资源ID的维度,以用作原始像素的大小.这与getDimension(int)相同,只是将返回的值转换为整数像素以用作大小.大小转换涉及舍入基值,并确保非零基值的大小至少为一个像素.

是的,它会使值四舍五入,但它并不是很糟糕(只是在hdpi和ldpi设备上的奇数值需要在ldpi不常见时添加一点值)我在xxhdpi设备中测试,将4dp转换为16(像素),这是真正.


Ric*_*725 7

基于 drspaceboo 的解决方案,借助 Kotlin,您可以使用扩展程序Float更轻松地转换为 Dips。

fun Float.toDips() =
        TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, resources.displayMetrics);
Run Code Online (Sandbox Code Playgroud)

用法:

(65f).toDips()
Run Code Online (Sandbox Code Playgroud)