Search code examples
androidtextviewellipsisspannablestring

Android - Ellipsize & Truncate all long Urls in a Textview


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:

enter image description here (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.


Solution

  • 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