Using Linkify.addLinks combine with Html.fromHtml

≡放荡痞女 提交于 2019-12-12 07:50:38

问题


I have a TextView that gets it's data set by calling this:

tv.setText(Html.fromHtml(myText));

The string myText contains partially formatted html data. For example, it might have font tags, but not have any url links formatted using <a href=...> tags. I was hoping to use the Linkify.addLinks(...) to do that since my text could include other types of links that Linkify would convert for me appropriately. So I wrote my code to look like this:

String myText = "<font color=\"red\">Red text</font> and Url: www.google.com";
tv.setText(Html.fromHtml(myText));
Linkify.addLinks(tv, Linkify.ALL);
tv.setMovementMethod(LinkMovementMethod.getInstance());

This does not work properly. Meaning that it processes the font tags but Linkify does not convert urls to UrlSpan properly.

Alternatively, if I call setText() without the Html.fromHtml(..), Linkify works but then I lose all the text formatted from the html font tags. Somehow they both seem to be conflicting and I can have only one or the other.

Now here's the interesting part that I dont understand. If I remove the Linkify code from java and go to my layout xml and put the following lines in there, all seems to be working (Linkify and fromHtml both end up playing nice together... somehow)

<TextView
    ... 
    android:autoLink="all"
    android:linksClickable="true"
    ...
/>

Can someone explain to me why that would make everything work??

I looked into the source code for TextView's setMovementMethod() and it eventually ends up calling:

setFocusable(true);
setClickable(true);
setLongClickable(true);

That should theoretically make everything work and behave the same as the xml layout code. I tried switching the order of calling Linkify.addLinks(..) before setText(Html.fromHtml(..)) in the java code, but that didn't make a difference.

Any ideas as to why combining Linkify.addLinks() and Html.fromHtml() in java would cause this behavior... but not in the xml layout?


回答1:


It's because Html.fromHtml and Linkify.addLinks removes previous spans before processing the text.

Use this code to get it work:

public static Spannable linkifyHtml(String html, int linkifyMask) {
    Spanned text = Html.fromHtml(html);
    URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);

    SpannableString buffer = new SpannableString(text);
    Linkify.addLinks(buffer, linkifyMask);

    for (URLSpan span : currentSpans) {
        int end = text.getSpanEnd(span);
        int start = text.getSpanStart(span);
        buffer.setSpan(span, start, end, 0);
    }
    return buffer;
}



回答2:


You can try this one:

First set the text in to your TextView.

tv.setText(myText);

Convert the links with Linkify

Linkify.addLinks(tv, Linkify.ALL);

and finally replace the text with Html.fromHtml but using the Linkified text from your EditText.

tv.setText(Html.fromHtml(tv.getText().toString()));



回答3:


100% works solution (kotlin).

Create class for store HtmlLink before Linkify

class HtmlLink(val urlSpan: URLSpan, val spanStart: Int, val spanEnd: Int)

Create spanned html (both formats for test)

val spanned = Html.fromHtml("https://google.com" +
                "<br><a href=\"https://google.com\">Google</a>")

Store html

val htmlLinks = ArrayList<HtmlLink>()
spanned.getSpans(0, spanned.length, URLSpan::class.java).forEach { urlSpan ->
    htmlLinks.add(HtmlLink(urlSpan, 
                  spanned.getSpanStart(urlSpan),
                  spanned.getSpanEnd(urlSpan)))
}

Create spannable builder and Linkify it

val builder = SpannableString(spanned)
Linkify.addLinks(builder, Linkify.WEB_URLS)

Restore spans.

htmlLinks.forEach { htmlLink ->
    builder.setSpan(URLSpan(htmlLink.urlSpan.url), htmlLink.spanStart, htmlLink.spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}

Set finally text

scrollContent.text = builder


来源:https://stackoverflow.com/questions/14538113/using-linkify-addlinks-combine-with-html-fromhtml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!