Paint.setStrokeWidth()使用的是什么单位?

50

Paint.setStrokeWidth() 方法使用的是什么单位?我是否需要根据当前屏幕密度来缩放该值?

这是一个浮点数值,所以我知道它不是像素数。它肯定是相对于某些东西的。

截至本篇文章撰写时,文档只有以下内容:

设置描边宽度。传递 0 以以发际线模式绘制轮廓。发际线总是独立于画布矩阵绘制单个像素。

3个回答

44

描边宽度以像素为单位定义(是的,它是浮点数,并且使用像素分数没有问题 :))


嗨,Romain,我尝试了ApiDemos中的PathEffect示例,那里的描边宽度设置为6。当我在我的hdpi手机屏幕上测量宽度时,它是9px。看起来初始描边宽度值被密度乘以了。我应该提供除以密度的值才能得到真实宽度吗? - k_shil
7
我不相信Romain的答案是正确的。在我的当前测试设备上(HTC One X,密度为2.0),我发现必须使用所需描边宽度除以1.5来调用.setStrokeWidth(),这样宽度才能确切地达到目标值。否则,宽度将会太宽。这个1.5倍因子与Zzokk发现的结果完全一致(6像素和9像素),但我怀疑它是否与屏幕密度有关,因为One X的密度是2.0而不是1.5。因此,这个1.5倍因子的来源目前让我感到困惑。 - Trevor
2
请注意,描边宽度受画布附加的变换影响。如果您调用canvas.scale(2.0f, 2.0f),则描边宽度也将乘以2.0。 - Torben
为了澄清一点,之所以没有记录下来是因为每个Java Android API都采用像素(除了与文本大小有关的某些东西),因此它是隐式的。 - Karu
我认为笔画宽度会受到缩放的影响。因此,如果您没有指定比例因子或变换矩阵,则它以像素为单位。如果您已经设置了缩放,则它以像素乘以比例因子的方式呈现。 - Edward Falk
显示剩余2条评论

29

setStrokeWidth使用像素。

因此,要将您的dps转换为绘画像素:

int dpSize =  10;
DisplayMetrics dm = getResources().getDisplayMetrics() ;
float strokeWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpSize, dm);
paint.setStrokeWidth(strokeWidth);

1
或者您可以将值粘贴到dimens.xml中,然后只需执行以下操作:paint.setStrokeWidth(getContext().getResources().getDimensionPixelSize(R.dimen.stroke_width)); - slott
这还是不行,我的笔画在不同的设备上都不一样,有人解决了吗? - 68060
@slott 这个值可以动态计算得出,因此不会在dimens.xml中。 - Fran Marzoa

3

如果您想尝试绘制自己的"画布边框",请记住一件事情:onDraw时即使描边也会被裁剪。因此,

paint.style = Paint.Style.STROKE
rect.set(0, 0, width, height)
paint.strokeWidth = 10F
canvas.drawRect(rect, paint)

将导致仅有5F宽度的“边框”。这是由于描边被居中放置在矩形上,而在此情况下,矩形是画布的边缘 - 结果是其一半实际上被剪辑掉了,因为它超出了画布。
要解决这个问题,只需将所需的边框厚度乘以2。[在上面的示例中,您需要设置strokeWidth = 20F,然后您将“看到”一条10F的描边。]

谢谢!这正是我想知道的事情,当我试图绘制一个1dp的矩形时,它看起来太窄了。我无法弄清楚,但这可以解释。实际上相当令人困惑... - Johan Paul

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