gpt4 book ai didi

Android:如何将 HTML 字符串转换为 Spanned 以在 TextView 中显示(必须在 API < 24 上工作)

转载 作者:行者123 更新时间:2023-12-02 13:34:01 29 4
gpt4 key购买 nike

对于我的应用程序,我需要将包含跨度(带有 背景颜色 )的 HTML 显示为 Spanned这样它就可以显示在 TextView 上, 作为 Android 的 TextView不支持 span标签。我首先尝试转换 StringSpannableStringBuilder ,然后从转换后的字符串 ( Spanned ) 中检索 HTML 编码的字符串。我需要它来处理 API 22-23,因此,我 不能简单地使用 fromHTML fromHTML不支持 span对于低于 24 的 API。我正在编写一个名为 fromHTML 的函数要做到这一点:
fromHTML 的输入示例(输入可以是任何带跨度的字符串):

Not highlighted string<span style=\"background-color: #FF8983\">Highlighted string</span> 
not highlighted string <span style=\"background-color: #FF8983\">Highlighted string</span>

下面是我的代码:
private fun fromHtml(source:String):Spanned {
var htmlText:SpannableStringBuilder = source as SpannableStringBuilder;
var htmlEncodedString:String = Html.toHtml(htmlText);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
return Html.fromHtml(htmlEncodedString, Html.FROM_HTML_MODE_LEGACY)
}
else
{
return Html.fromHtml(htmlEncodedString)
}
}

但是,我收到以下错误:

java.lang.ClassCastException: java.lang.String cannot be cast to android.text.SpannableStringBuilder



如何将 HTML 字符串转换为 Spanned 对象以在 TextView 上显示( 我需要此程序在 API 22-23 上工作,而在 API 22-23 上,不支持 span,所以我不能只使用简单的fromHTML 转换 ?

最佳答案

您正在获得类转换异常,因为您试图将字符串转换为 SpannableStringBuilder。

var htmlText:SpannableStringBuilder = source as SpannableStringBuilder
将字符串放入 SpannableStringBuilder 的方法是
var htmlText = SpannableStringBuilder(source)
关于对 24 以下 API 的 HTML span 标签支持,我认为 HtmlCompat 会为 API 24 功能提供 span 标签支持,但事实并非如此。这意味着我们必须自己处理 span 标签。 (由于 API 24 下不支持 span 标签,我们可能会考虑使用 HTML 标签处理程序。不幸的是,标签处理程序会收到 span 标签存在的警报,但标签处理程序无法使用 span 属性:- (,所以我们必须做以下事情。)
下面的示例代码将处理 background-color API 18+ 的 span 标签的属性。 (它也可能支持低于 18 的 API。)方法是使用正则表达式从 HTML 中提取适当的跨度属性值和文本,并将它们转换为跨区字符串中的 Android 文本跨度。然后可以将跨越的字符串设置为 TextView。您可以在代码中找到解释性注释。
这是运行 API 18 的模拟器上的屏幕外观。高亮显示由下面的代码创建,而粗体文本是通过调用 Html.fromHtml() 创建的。
enter image description here
MainActivity.kt
class MainActivity : AppCompatActivity() {
// Html.fromHTML() seems to be a little picky about how HTML attributes are delimited.
// Mind the spaces!
private val mHtmlString =
" <span style=\"color: #FFFFFF ; background-color: #FF8983\">Highlighted</span><b> Bold!</b> Not bold <span style=\"background-color: #00FF00\">string</span>"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val tv = findViewById<TextView>(R.id.textView)
tv.text = processHtml(mHtmlString)
}

private fun processHtml(s: String): Spanned? {

// Easy for API 24+.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return HtmlCompat.fromHtml(s, HtmlCompat.FROM_HTML_MODE_LEGACY)
}

// HtmlCompat.fromHtml() for API 24+ can handle more <span> attributes than we try to here.
// We will just process the background-color attribute.

// HtmlCompat.fromHtml() will remove the spans in our string. Escape them before processing.
var escapedSpans = s.replace("<span ", "&lt;span ", true)
escapedSpans = escapedSpans.replace("</span>", "&lt;/span&gt;", true)

// Process all the non-span tags the are supported pre-API 24.
val spanned = HtmlCompat.fromHtml(escapedSpans, HtmlCompat.FROM_HTML_MODE_LEGACY)

// Process HTML spans. Identify each background-color attribute and replace the effected
// text with a BackgroundColorSpan. Here we assume that the background color is a hex number
// starting with "#". Other value such as named colors can be handled with additional
// processing.
val sb = SpannableStringBuilder(spanned)
val m: Matcher = SPAN_PATTERN.matcher(sb)
do {
if (m.find()) {
val regionEnd = m.start(0) + m.group(2).length
sb.replace(m.start(0), m.end(0), m.group(2))
.setSpan(
BackgroundColorSpan(parseInt(m.group(1), 16) or HTML_COLOR_OPAQUE_MASK),
m.start(0),
regionEnd,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
m.reset(sb)
m.region(regionEnd, sb.length)
}
} while (!m.hitEnd())
return sb
}

companion object {
val SPAN_PATTERN: Pattern =
Pattern.compile("<span.*?background(?:-color)?:\\s*?#([^,]*?)[\\s;\"].*?>(.*?)</span>")
const val HTML_COLOR_OPAQUE_MASK = 0xFF000000.toInt()
}
}

关于Android:如何将 HTML 字符串转换为 Spanned 以在 TextView 中显示(必须在 API < 24 上工作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59595453/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com