Android:Canvas.drawText()在不同屏幕分辨率下的文本大小

37

对于我的Android游戏,我需要调用Canvas.drawText()

在测试时,我使用标准字体大小,看起来效果很好。

然而,当我将分辨率提高到更高的密度时,大图像会自动加载,但文本现在非常小。

有没有一种简单的方法来计算应该绘制文本的大小,或者我必须手动完成这个过程?

编辑:@Suragch,编辑我的帖子的目的是什么?


尝试过使用scaledDensity吗? - Marcin Gil
嗨Marcin,是的,我用过那个,但乘数似乎没有什么作用。据我所知,我也在使用正确的乘法逻辑。 - twig
4个回答

83

最简单的方法是使用与屏幕密度无关的像素单元(sp)在资源中定义字体大小。这个单位类似于密度无关像素(dpdip),因为它考虑了屏幕密度,同时还考虑了用户的字体大小设置。

要添加新的尺寸,请在res/values文件夹中创建一个dimens.xml文件,并输入以下代码以添加一个名为myFontSize的新尺寸:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="myFontSize">20sp</dimen>
</resources>

您可以使用以下方法在应用程序中获取文本大小:

int scaledSize = getResources().getDimensionPixelSize(R.dimen.myFontSize);

生成的大小将正确缩放以考虑当前屏幕密度和字体大小设置。

有关更多信息,请参见Android开发者文档资源页面


有趣的方法,我一定会在有机会的时候尝试一下。 - twig
谢谢Joseph,这个方法非常有效。我必须承认我一开始把它应用在了错误的Paint对象上,后来才意识到。Marcin的解决方案也可以正常工作。 - twig
Joseph,你是说要添加R.dimen.font_size并将其设置为20sp。然后通过调用此函数,20sp将自动缩放到任何屏幕大小?还是我们需要为每个屏幕分辨率添加多个font_size维度? - HGPB
我不明白为什么这不是默认行为。 - ElYeante
一种类似的方法,不需要资源文件。https://dev59.com/w3A75IYBdhLWcg3w3NHf#3062023 - CrandellWS

7

您可以通过简单的数学运算自行完成:

您需要计算一种关系,以便使您的文本在任何画布大小下都保持相同的大小。因此,请使用实际画布大小,例如:

double relation = Math.sqrt(canvas.getWidth() * canvas.getHeight());

但是这个数字太大了,所以将其除以一个适合您需求的数字,比如说250:

relation = relation / 250;

现在您可以像这样设置文本大小:
paint.setTextSize((float) (myFontSize * relation));

您不必将关系分为任何数量,但在这种情况下,您将不得不使用非常小的字体大小来设置变量 myFontSize 。 对于我来说,250适用于使用普通字体大小,这些字体大小会自动调整到任何屏幕尺寸,因为您已经考虑了画布的像素尺寸。


我在不同的模拟器上测试了'myPaint.setTextSize(80)'(在'canvas.drawText'之前调用),包括Nexus One=480x800到Nexus XL=1440x2560,文本大小始终相同(例如屏幕上始终为1个“实际”厘米)。不确定是否在某一时刻更改过此设置(我使用Java 8 / API 27),但似乎无需计算大小,因为画布会自动按比例缩放。 - Neph
更新:我现在已经用不同的模拟器测试了您的建议,但它并没有产生期望的结果:例如,在Pixel XL(1440x2560,560dpi)上使用字体大小22(使用您的代码)看起来很好,但在Nexus One(480x800,hdpi = 240dpi)上,它变得非常小/无法阅读。 - Neph

4

最简单的方法是在您的资源目录中使用 可缩放独立像素 (sp) 或者 密度独立像素 (dp) 单位来定义字体大小。然后通过以下方式获取文本大小:

int scaledSize = getResources().getDimensionPixelSize(R.dimen.font_size);
mTextView.setTextSize(scaledSize);

这将根据当前屏幕密度/分辨率和用户的字体大小设置适当地缩放文本大小。

如何在资源目录中定义字体大小?

在文件夹res->values中创建一个名为dimens.xml的文件。然后复制以下代码。

<resources>
    <dimen name="font_size">25sp</dimen>   // sp or dp accordingly
</resources>
< p >标签中的< code > name < / code >属性将被用作资源ID。< / p >

1
http://developer.android.com/guide/topics/resources/more-resources.html#Dimension - Trung

2
调用Canvas.drawText()时,文本大小首先由传入的Paint对象确定,可以通过Paint.setTextSize()设置。文本大小会根据画布密度自动缩放,可以使用Canvas.getDensity()找到画布密度。
在设置将绘制在画布上的画笔对象的文本大小时,使用dpsp作为单位值,并让Canvas为您处理缩放。

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