Can I change the text of a TextView link after using Linkify?

Is it possible to change TextView text after using Linkify to create links? I have something where I want the url to have two fields, a name and an identifier, but then I just want the text to display the name.

So, I start with a text field with text that includes both the name and the identifier, as well as a link to create the corresponding links with both fields. But for display, I do not want to show the identifier.

Is it possible?

+3
source share
2 answers

This is a pain, but yes. So Linkify basically does a few things. First, it scans the contents of the text box for the strings that match the strings of the URL. Then he creates UrlSpan and ForegroundColorSpan for those sections that correspond to him. Then it sets the MovementMethod from the TextView.

The important part here is UrlSpan. If you take a TextView and call getText (), notice that it returns CharSequence. This is most likely some kind of Spanned. From Spanned, you can ask getSpans () and explicitly UrlSpans. Once you know all the gaps you can do, scroll through the list and find and replace the old span objects with the new span objects.

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 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);
}

Hope this makes sense. Linkify is just a good tool for setting the correct intervals. Whitespace is simply interpreted when rendering text.

+8

. , . , . , . Kotlin, , Java.

, Spannable . URL- URL- URL-, Linkify.

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
}
0

Source: https://habr.com/ru/post/1770640/


All Articles