4

使用 Linkify 创建链接后是否可以更改 TextView 文本?我有一些东西,我希望 url 有两个字段,一个名称和 id,但我只希望文本显示名称。

因此,我从一个包含名称和 ID 的文本视图开始,然后链接化以创建包含两个字段的适当链接。但是对于显示,我不想显示 id。

这可能吗?

4

2 回答 2

9

这有点痛苦,但是是的。所以 Linkify 基本上做了几件事。首先,它会扫描 textview 的内容以查找与 url 匹配的字符串。接下来,它为匹配它的部分创建 UrlSpan 和 ForegroundColorSpan。然后它设置 TextView 的 MovementMethod。

这里的重要部分是 UrlSpan 的。如果您使用 TextView 并调用 getText(),请注意它会返回一个 CharSequence。它很可能是某种跨度。您可以从 Spanned 中询问 getSpans() ,特别是 UrlSpans。一旦您知道所有这些跨度,您就可以遍历列表并找到旧的跨度对象并将其替换为新的跨度对象。

mTextView.setText(someString, TextView.BufferType.SPANNABLE);
if(Linkify.addLinks(mTextView, Linkify.ALL)) {
 //You can use a SpannableStringBuilder here if you are going to
 // manipulate the displayable text too. However if not this should be fine.
 Spannable spannable = (Spannable) mTextView.getText();
 // Now we go through all the urls that were setup and recreate them with
 // with the custom data on the url.
 URLSpan[] spans = spannable.getSpans(0, spannable.length, URLSpan.class);
 for (URLSpan span : spans) {
   // If you do manipulate the displayable text, like by removing the id
   // from it or what not, be sure to keep track of the start and ends
   // because they will obviously change.
   // In which case you may have to update the ForegroundColorSpan's as well
   // depending on the flags used
   int start = spannable.getSpanStart(span);
   int end = spannable.getSpanEnd(span);
   int flags = spannable.getSpanFlags(span);
   spannable.removeSpan(span);
   // Create your new real url with the parameter you want on it.
   URLSpan myUrlSpan = new URLSpan(Uri.parse(span.getUrl).addQueryParam("foo", "bar");
   spannable.setSpan(myUrlSpan, start, end, flags);
 }
 mTextView.setText(spannable);
}

希望这是有道理的。Linkify 只是一个设置正确 Span 的好工具。跨度只是在渲染文本时被解释。

于 2010-10-21T07:29:36.767 回答
0

格雷格的回答并没有真正回答最初的问题。但它确实包含一些关于从哪里开始的见解。这是您可以使用的功能。它假定您在此调用之前已链接您的文本视图。它在 Kotlin 中,但如果您使用 Java,您可以了解它的要点。

简而言之,它使用您的新文本构建了一个新的 Spannable。在构建期间,它会复制 Linkify 调用之前创建的 URLSpan 的 url/flags。

fun TextView.replaceLinkedText(pattern: String) { // whatever pattern you used to Linkify textview
    if(this.text !is Spannable) return // no need to process since there are no URLSpans
    val pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE)
    val matcher = pattern.matcher(this.text)
    val linkifiedText = SpannableStringBuilder()
    var cursorPos = 0
    val spannable = this.text as Spannable
    while (matcher.find()) {
        linkifiedText.append(this.text.subSequence(cursorPos, matcher.start()))
        cursorPos = matcher.end()
        val span = spannable.getSpans(matcher.start(), matcher.end(), URLSpan::class.java).first()
        val spanFlags = spannable.getSpanFlags(span)
        val tag = matcher.group(2) // whatever you want to display
        linkifiedText.append(tag) 
        linkifiedText.setSpan(URLSpan(span.url), linkifiedText.length - tag.length, linkifiedText.length, spanFlags)
    }
    this.text = linkifiedText
}
于 2017-01-12T02:53:22.610 回答