使用Linkify后,我可以更改TextView链接文本吗?

使用Linkify创建链接后,是否可以更改TextView文本? 我有我想要的网址有两个领域,一个名称和编号,但我只是希望文本显示名称。

因此,我首先使用包含名称和ID的文本的textview,并链接到两个字段创建适当的链接。 但对于显示器,我不想显示ID。

这可能吗?

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

这里的重要部分是UrlSpan的。 如果你把你的TextView和调用getText(),注意它返回一个CharSequence。 这很可能是某种Spanned。 从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只是一个很好的工具来设置正确的跨度。 Spans在渲染文本时会被解释。

格雷格的答案并没有真正回答原来的问题。 但是它确实包含了一些从哪里开始的见解。 这是一个你可以使用的功能。 它假定你已经在这个调用之前链接了你的textview。 这是在Kotlin,但是如果你使用Java,你可以得到它的要点。

简而言之,它会用新的文本构建一个新的Spannable。 在构建过程中,它会复制之前创建的Linkify调用的URLSpans的url /标志。

 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 }