在代码和资源文件中设置TextView字体大小时出现不一致问题

68

官方文档似乎没有回答这个问题,或者我无法理解。

元素(忽略AlertDialog,在任何TextView中都会出现):

TextView tv = (TextView) dialog.findViewById(android.R.id.message);

不一致。情况A:

tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
// or tv.setTextSize(14); does the same

案例B:
tv.setTextSize(getResources().getDimension(R.dimen.text_size_small));
// TypedValue makes no difference either.

其中values/dimens.xml包含:

<dimen name="text_size_small">14sp</dimen>

结果:字体大小不同,从资源中检索时显得更大。我可能错过了什么,所以我的错误是什么,最重要的是:为什么?
--第一个答案的更新--
固定数字只是一个例子,因为没有人会在代码中硬编码固定字体大小。所以让我重新表述问题:
为什么如果我从代码中获取资源,文本大小比我从XML布局中获取资源时要大?此外,问题仍然是相同的:如何在代码中检索14sp单位并使其与布局XML中设置的14sp单位保持一致?我没有接受答案,因为它没有告诉我如何在代码中使用来自资源的sp单位来设置文本大小。
在这个布局中,字体大小不同,即使维度相同:
<TextView
            android:id="@+id/my_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/TextBody" />

styles.xml:

<style name="TextBody">
    <item name="android:textSize">@dimen/text_size_small</item>
    <item name="android:lineSpacingMultiplier">1.1</item>
    <item name="android:textColor">@color/body_text_1</item>
    <item name="android:textIsSelectable">true</item>
    <item name="android:linksClickable">true</item>
</style>

看到那个text_size_small了吗?为什么在这种情况下,使用相同的dimen资源,字体大小比代码中要小呢?


感谢您提出这个问题。我在我的项目中也遇到了这个问题。 - anticafe
“固定数字只是一个例子,因为没有人会在代码中硬编码固定字体大小。所以让我重新表述问题” - 这完全不是真的,在 attrs xml 文件中硬编码 Dimen 值并被屏幕尺寸覆盖是控制 Android 文本大小的可靠方法。 - Rowan Berry
当我提出问题时,我甚至不知道在Android中如何检索字体尺寸的基础知识,正如我对Nikola的回答所述。此外,如果我理解您的问题正确,当我只考虑我自己面临的问题时,我绝对不应该说“任何人”。这只是一种强调,在这里设置Java端并不是我的关注点。感谢您对此进行纠正。 - davidcesarino
3个回答

111

你应该使用setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);,因为getDimension方法的文档说明它返回一个由适当指标乘以资源维度值得到的值。我理解这是预先计算的绝对像素值。

也就是说,使用以下代码:

tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.text_size_small));

谢谢。我猜这就是Nikola试图表达的意思(现在我看到了),但是你的解释让我理解了问题的根源。 - davidcesarino

26

不知何故,这似乎很合适:

XML:

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

Java:

setTextSize(TypedValue.COMPLEX_UNIT_SP, 9);
setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen.typo14));

1
感谢您提供的代码,非常直观地展示了解决方案。总的来说,这基本上就是maxmc所说的...使用像素单位的setTextSize从资源中检索。 - davidcesarino
1
我有一个自定义控件,它的 textSize 是使用 sp 设置的。当你使用 getDimensionPixelSize 获取该值时,它会被转换为像素。然后,当文本大小被设置时,默认为 sp(或类似),因此大小太大了。这对我帮助很大。 - JeffRegan

2

这涉及到 sppxdpi

tv.setTextSize(14) = 14 pixels 

那只是一个例子...我不会在代码中使用硬编码单位。我更新了我的问题以澄清。问题是,我从同一资源获取的字体大小不一致,具体取决于我是在布局中检索还是在代码中检索。这就是我试图解决的问题。 - davidcesarino

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