Reputation: 5111
I have a textview which can contain links like https://www.google.com and hyper links with anchor tag Google
Now, I have added the below properties on this textview.
Linkify.addLinks(textview, Linkify.WEB_URLS);
textview.setMovementMethod(LinkMovementMethod.getInstance());
But the links like https://www.google.com these are coming fine in blue and redirecting to the page but anchor tags are not coming in blue and they are not redirecting it.
So, I want to make my textview to render both type of links: direct links and hyper links. How can I do this.
Upvotes: 1
Views: 641
Reputation: 21
//the string to add links to
val htmlString = "This has anchors and urls http://google.com also <a href=\"http://google.com\">Google</a>."
//Initial span from HtmlCompat will link anchor tags
val htmlSpan = HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_LEGACY) as Spannable
//save anchor links for later
val anchorTagSpans = htmlSpan.getSpans(0, htmlSpan.length, URLSpan::class.java)
//add first span to TextView
textView.text = htmlSpan
//Linkify will now make urls clickable but overwrite our anchor links
Linkify.addLinks(textView, Linkify.ALL)
textView.movementMethod = LinkMovementMethod.getInstance()
textView.linksClickable = true
//we will add back the anchor links here
val restoreAnchorsSpan = SpannableString(textView.text)
for (span in anchorTagSpans) {
restoreAnchorsSpan.setSpan(span, htmlSpan.getSpanStart(span), htmlSpan.getSpanEnd(span), Spanned.SPAN_INCLUSIVE_INCLUSIVE)
}
//all done, set it to the textView
textView.text = restoreAnchorsSpan
Upvotes: 0
Reputation: 1806
It's mentioned in javadoc of Linkify#addLinks(Spannable, Int)
that:
...If the mask is nonzero, it also removes any existing URLSpans attached to the Spannable, to avoid problems if you call it repeatedly on the same text.
Although it is not mentioned in Linkify#addLinks(TextView, Int)
which you're using, it appears that they follow the same behavior and existing links (i.e. the 'anchor tags' in your question) would be removed before linkify.
To workaround and preserve existing links ('anchor tags' in your case), you need to backup existing spans (i.e. TextView#getText
--> convert to Spanned --> use Spanned#getSpans
to list existing links --> use Spanned#getSpanStart
and Spanned#getSpanEnd
and Spanned#getSpanFlags
to retrieve the settings of each)
After linkify, re-add the spans (i.e. TextView#getText
--> convert to Spannable
--> use Spannable#setSpan
to re-add the links --> Set the Spannable
back with TextView#setText
)
Depending on your case, you might also need to check for overlapping 'anchor tags' and 'linkify links' and adjust accordingly...
As you see, this is quite tedious and complex and error prone to code. To simplify things, I have just incorporate all these into Textoo library for reuse and sharing. With Textoo, you can achieve the same by:
TextView myTextView = Textoo
.config((TextView) findViewById(R.id.view_location_disabled))
.linkifyWebUrls()
.apply();
Textoo will preserve exiting links and linkify all non-overlapping web urls.
Upvotes: 0
Reputation: 30985
Linkify
(the way you've invoked it) only knows to convert things that actually look like web URLs (i.e. they begin with http or https, followed by colon and two slashes, etc. etc).
If you want to convert something else into links, you will have to add some more parameters to Linkify
to give it more smarts to convert what you want. You can create a MatchFilter and a TransformFilter then call Linkify.addLinks(TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter)
But it looks to me like you want to take a word like "Google" and add a link for "https://www.google.com". That's not something that can be scanned. For that, you need to use a SpannableStringBuilder
. Your code might look something like this:
String text = "This is a line with Google in it.";
Spannable spannable = new SpannableString(text);
int start = text.indexOf("Google");
int end = start + "Google".length();
URLSpan urlSpan = new URLSpan("https://www.google.com");
spannable.setSpan(urlSpan, start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(spannable);
Upvotes: 1