使用Linkify创建链接后是否可以更改TextView文本?我有一些东西,我希望网址有两个字段,一个名称和ID,但我只想让文字显示名称。
所以我开始使用包含name和id的文本的textview,并使用linkify创建两个字段的相应链接。但对于显示器,我不想显示id。
这可能吗?
答案 0 :(得分:9)
这是一种痛苦但是是的。所以Linkify基本上做了一些事情。首先,它扫描textview的内容以查找与url匹配的字符串。接下来,它会为匹配它的那些部分创建UrlSpan和ForegroundColorSpan。然后它设置TextView的MovementMethod。
这里的重要部分是UrlSpan。如果您使用TextView并调用getText(),请注意它返回CharSequence。它很可能是某种跨越式的。从Spanned你可以询问,getSpans()和特定的UrlSpans。一旦了解了所有这些跨度,就可以循环遍历列表,并使用新的span对象查找并替换旧的span对象。
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的一个很好的工具。 Spans只是在渲染文本时得到解释。
答案 1 :(得分:0)
简而言之,它会使用您的新文本构建一个新的Spannable。在构建期间,它会复制以前创建的Linkify调用的URLSpans的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
}