Android - Ellipsize & Truncate all long Urls in a Textview

蹲街弑〆低调 提交于 2019-12-08 07:53:13

问题


In my android app's textview, I want to ellipsis all URLs (which already have been linked using clickable span) to get ellipsis (or truncate) if the length of URL is greater than a certain limit.

This behaviour is inspired from twitter and facebook.

For example, the link http://www.getfluttr.com/flap/3rL7/now-only-if-modi-would-listen-to-opposition-party-/ it should look something like this:

(Screenshot Source: Twitter)

I understand that this has to involve spans. I can't seem to be able to find a span that'll allow me to replace text while keeping link.


回答1:


the following code will do the trick for you

public class LinkShortener {

    public static final int MAX_LINK_LENGTH = 20;

    public static CharSequence shortenLinks(String text) {
        return shortenLinks(text, Linkify.ALL);
    }

    public static CharSequence shortenLinks(String text, int linkMask) {
        SpannableStringBuilder builder = new SpannableStringBuilder(text);
        Linkify.addLinks(builder, linkMask);
        URLSpan[] spans = builder.getSpans(0, builder.length(), URLSpan.class);
        for (URLSpan span : spans) {
            int start = builder.getSpanStart(span);
            int end = builder.getSpanEnd(span);
            int flags = builder.getSpanFlags(span);

            CharSequence linkText = builder.subSequence(start, end);
            if (linkText.length() > MAX_LINK_LENGTH) {
                linkText = linkText.subSequence(0, 20) + "…";
                builder.replace(start, end, linkText);
                builder.removeSpan(span);
                builder.setSpan(span, start, start+linkText.length(), flags);
            }
        }
        return builder;
    }
}

Then you can simply use it like this:

 itemView.setText(LinkShortener.shortenLinks("https://example.com/really_long_url"));

You might need to disable autoLink on the text view

The code first linkifies the text using the build in Android tooling. Then it goes through all creates URLSpans, and shortens the text via replace. Lastly we change the span to make sure it has the right bounds. Since we are reusing the existing span, the URL will be preserved




回答2:


I added some "pretty" updates to @Filip Wieladek answer based on Twitter behaviour. The provided code first removes the http(s)://www. prefixes providing up to 12 characters for more usefull information. It also perfectly matches the question desired behaviour. Example:

  • https://www.stackove... (20 chars)
  • stackoverflow.com/que... (20 chars without prefix)

Code

public static CharSequence shortenLinks(String text, int linkMask) {
    SpannableStringBuilder builder = new SpannableStringBuilder(text);
    Linkify.addLinks(builder, linkMask);
    URLSpan[] spans = builder.getSpans(0, builder.length(), URLSpan.class);
    for (URLSpan span : spans) {
        int start = builder.getSpanStart(span);
        int end = builder.getSpanEnd(span);
        int flags = builder.getSpanFlags(span);

        CharSequence linkText = builder.subSequence(start, end);
        if (linkText.length() > MAX_LINK_LENGTH) {

            // 1 - Remove the https:// or http:// prefix
            if(linkText.toString().toLowerCase().startsWith("https://"))
                linkText = linkText.subSequence("https://".length(), linkText.length());
            else if(linkText.toString().toLowerCase().startsWith("http://"))
                linkText = linkText.subSequence("http://".length(), linkText.length());

            // 2 - Remove the www. prefix
            if(linkText.toString().toLowerCase().startsWith("www."))
                linkText = linkText.subSequence("www.".length(), linkText.length());

            // 3 - Truncate if still longer than MAX_LINK_LENGTH
            if (linkText.length() > MAX_LINK_LENGTH) {
                linkText = linkText.subSequence(0, MAX_LINK_LENGTH) + "…";
            }

            // 4 - Replace the text preserving the spans
            builder.replace(start, end, linkText);
            builder.removeSpan(span);
            builder.setSpan(span, start, start+linkText.length(), flags);
        }
    }
    return builder;
}


来源:https://stackoverflow.com/questions/33203359/android-ellipsize-truncate-all-long-urls-in-a-textview

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