如何为旧版 Android API 实现 TextView 行间距方法?
Posted
技术标签:
【中文标题】如何为旧版 Android API 实现 TextView 行间距方法?【英文标题】:How to implement TextView line spacing methods for older Android API? 【发布时间】:2015-12-09 08:41:17 【问题描述】:之前,我在 *** 上问了一个标题为“How to paginate text in android”的问题,得到了一个很好的答案,对我帮助很大。现在我需要将代码移植到较旧的 Android API 上,以防万一,Android API 版本 8,这样我就可以在几乎所有 Android 设备上运行我的应用程序,从 Android 2.2 开始。
我遇到的问题是答案中使用的某些方法仅在Android API 16+中可用。
mPagination = new Pagination(mText,
mTextView.getWidth(),
mTextView.getHeight(),
mTextView.getPaint(),
mTextView.getLineSpacingMultiplier(),
mTextView.getLineSpacingExtra(),
mTextView.getIncludeFontPadding());
所以,我至少要实现这些方法:
TextView.getLineSpacingMultiplier()
TextView.getLineSpacingExtra()
TextView.getIncludeFontPadding()
第二个好像已经被here描述为:
mTextView.getPaint().getFontSpacing()
* mTextView.getLineSpacingMultiplier() + mTextView.getLineSpacingExtra()
但是我不知道另外两个在2.2中是否相关,如果是,如何在Android API版本8中实现。有一些提示here,使用Android的源代码TextView
我无法完全理解。
【问题讨论】:
见androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/…和androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/…和androidxref.com/5.1.1_r6/xref/frameworks/base/core/java/android/… @pskink 跟踪这些私有字段的变化源并不容易,所以我只是将它们替换为默认值:1.0f
、0.0f
和 true
以使其正常工作。但我不知道可能的副作用。
@pskink 这些方法返回私有字段。复制这些字段的默认值很容易,但是通过代码跟踪这些字段的更改,并复制根据配置更改这些字段的完全相同的行为并不容易,至少对我来说是这样。例如,如果是attr==com.android.internal.R.styleable.TextView_lineSpacingMultiplier
,那么mSpacingMult = a.getFloat(attr, mSpacingMult)
依赖于attr
和a
哪个a=context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes)
,并且这种依赖关系还在继续。
@Onik 抱歉,感谢您关注我的问题。 :-/ 我想出了如何(部分)通过使用默认值来解决问题,并忽略其余代码!我想问另一个关于你的解决方案的问题,关于我在那里遇到的 RTL 问题。
@Ho1 好的。如果您找到了解决方案,您可能希望发布您自己问题的答案,或者,如果它不是解决方案,只是解决问题的方法,请编辑发布新结果的问题。关于 RTL 问题,您也可能会提出一个新问题以获得更好的解决方案...而不是注释 here
【参考方案1】:
如果我们查看TextView's
来源,我们可以看到以下内容。
在Android 5.0
:
private float mSpacingMult = 1.0f;
private float mSpacingAdd = 0.0f;
...
private boolean mIncludePad = true;
在Android 2.0
:
private float mSpacingMult = 1;
private float mSpacingAdd = 0;
...
private boolean mIncludePad = true;
所以默认值是相等的。
话虽如此,您可以将Pagination's
构造函数与适用于API 8+
的默认值一起使用:
new Pagination(mText,
mTextView.getWidth(),
mTextView.getHeight(),
mTextView.getPaint(),
1.0f, 0.0f, true);
如果您让用户更改/设置(通过设置菜单)这些参数,同样无需使用getters
。您只需使用TextView's
setters
之一设置参数的新值,并将相同的值传递给Pagination's
构造函数。例如,
new Pagination(mText,
mTextView.getWidth(),
mTextView.getHeight(),
mTextView.getPaint(),
newValueOfSpacingMultiplier,
newValueOfSpacingExtra,
newValueOfIncludeFontPadding);
编辑
我想说的是,没有必要“在 Android API 版本 8 中实现它们”。一旦设置参数在TextView's
生命周期内永远不会改变。你可以通过一个简单的测试来检查它。只需在设置任何文本之前(例如,在 sample code 的 onCreate()
中)和之后(在 onGlobalLayout()
中,在 mPagination
初始化之后或在 update()
方法中)查看它们的值。
将TextView
的所有参数传递给Pagination's
构造函数的想法是在TextView
和Pagination
的引擎盖下使用Layout
类的相同配置实例。因此,与其将参数传递给先前使用getters
从TextView
检索的Pagination's
构造函数,您可以通过将您想要的任何值传递给Pagination
并将相同的值设置为@ 来实现相同配置的Layout
987654352@ 和正确的 setters
在 API version 8
中已经遇到。
【讨论】:
@Ho1 但是,从 "...通过代码跟踪这些字段的更改,并复制更改这些字段的完全相同的行为..." 我似乎就像您认为这些参数在TextView
内的文本处理过程中发生变化一样。我对吗?因为我在源代码中没有注意到类似的东西,所以在测试它时。即,如果我们在 TextView
初始化之后立即查看这 3 个参数,然后在 onGlobalLayout()
(视图已经用文本绘制的地方,包括跨区)查看,参数的值是一样。
@Ho1 所以,总而言之,我不必担心“将代码移植到旧的Android API”,只需按照答案使用它们即可。
@Ho1 继续编辑答案,希望能澄清我对使用Pagination
类的想法。真的有兴趣听听您的意见或怀疑吗? :)以上是关于如何为旧版 Android API 实现 TextView 行间距方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何为小于 24 的 API 添加 Android 网络安全配置
如何为 android 制作更长的 facebook Graph API 会话