如何为Paint.setTextSize()设置单位

68

Paint.setTextSize()中更改单位是否可能?据我所知,它是以像素为单位的,但我希望以DIP为单位设置文本大小以支持多屏幕。

5个回答

92

我知道这个话题已经老旧并且已经有了答案,但我也想建议这段代码:

int MY_DIP_VALUE = 5; //5dp

int pixel= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                              MY_DIP_VALUE, getResources().getDisplayMetrics());

1
文本大小应该使用 SP 而不是 DP。 - mathematics-and-caffeine

51

按照以下方式进行转换

// The gesture threshold expressed in dip
private static final float GESTURE_THRESHOLD_DIP = 16.0f;

// Convert the dips to pixels
final float scale = getContext().getResources().getDisplayMetrics().density;
mGestureThreshold = (int) (GESTURE_THRESHOLD_DIP * scale + 0.5f);

// Use mGestureThreshold as a distance in pixels

从这里开始 http://developer.android.com/guide/practices/screens_support.html#dips-pels


1
另一种类似的方法是使用资源文件。https://dev59.com/bG435IYBdhLWcg3whQc5#5369766 - CrandellWS
这怎么帮助到任何地方呢..? - james04

45

接受的答案是关于手势的,而不是设置文本大小的。在撰写本文时,得票最高的答案接近正确,但文档建议使用sp而不是dp,因为除了被缩放以适应屏幕密度(像dp值一样)之外,sp还根据用户首选字体大小进行缩放。

从代码中的整数

int spSize = 17;
float scaledSizeInPixels = spSize * getResources().getDisplayMetrics().scaledDensity;
mTextPaint.setTextSize(scaledSizeInPixels);

或者另一种选择

int spSize = 17;
float scaledSizeInPixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
        spSize, getResources().getDisplayMetrics());
mTextPaint.setTextSize(scaledSizeInPixels);

来自资源

或者如果您在资源中拥有spdp值:

<resources>
    <dimen name="fontSize">17sp</dimen>
</resources>

随着

float scaledSizeInPixels = getResources().getDimensionPixelSize(R.dimen.fontSize);
mTextPaint.setTextSize(scaledSizeInPixels);

其他链接


我测试了你的建议,但它们都存在同样的问题:例如字体大小22在Pixel XL(1440x2560,560dpi)上看起来很好,但在Nexus One(480x800,hdpi = 240dpi)上变得非常小/不可读。其他人建议使用这个,但会导致相同的问题发生。最好使用硬编码像素大小(例如myPaint.setTextSize(80)),因为这样文本在每个设备上的实际宽度(例如0.5英寸)将是相同的(画布会缩放它!)- 即使它显然不会随着Android的“字体大小”设置而缩放。 - Neph
@Neph,我已经有一段时间没有处理这个了。将“dp”值设置为“80”是否与使用“myPaint.setTextSize(80)”相同? - Suragch
老实说,我真没想到会在这么长时间后得到答案,所以谢谢你!你是说,用dp而不是sp来使用<dimen name =“ fontSize”> 17sp </ dimen>?我也试过用dp,但两者的结果都相同:22sp/22dp给我的结果与myPaint.setTextSize(80)几乎相同-至少对于更大的Pixel XL。在较小的Nexus One上,文本太小无法阅读。 - Neph
好的,我不确定发生了什么事情,但感谢您的评论。 - Suragch

4

如果你的Paint对象用于在Canvas上绘制文本,你可以让Canvas来处理缩放。

调用Canvas.drawText()时,文本大小首先由传入的Paint对象确定,该对象可以通过Paint.setTextSize()设置。文本大小会根据Canvas的密度自动缩放,可以使用Canvas.getDensity()进行查找。

在设置将要绘制在Canvas上的paint对象的文本大小时,请使用dp或sp作为单位,让Canvas为您处理缩放。


2
Paint.setTextSize(float textSize) 中,textSize 是以像素为单位的值。我不确定它是否会自动缩放。如果是的话,我认为文档应该说明单位是 spdp 而不是像素。 - Suragch
我的应用程序使用Canvas.drawText()设置地图标记。我尝试了不同的解决方案,但是像getDimensionPixelSize(R.dimen.fontSize)这样的建议不能正常工作:<dimen name="fontSize">22sp</dimen>在Pixel XL(1440x2560,560dpi)上看起来很好,在Nexus 4(768x1280,xhdpi=320dpi)上明显较小,但在Nexus One(480x800,hdpi=240dpi)上则非常小/无法阅读。TextView会自动缩放,但画布也会处理某些缩放:它不会对Android的字体设置进行更改,但它会确保文本在每个设备上的大小相同(例如0.5英寸宽)。 - Neph

4

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