android ellipsize multiline textview

115,481

Solution 1

Here is a solution to the problem. It is a subclass of TextView that actually works for ellipsizing. The android-textview-multiline-ellipse code listed in an earlier answer I have found to be buggy in certain circumstances, as well as being under GPL, which doesn't really work for most of us. Feel free to use this code freely and without attribution, or under the Apache license if you would prefer. Note that there is a listener to notify you when the text becomes ellipsized, which I found quite useful myself.

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.widget.TextView;

public class EllipsizingTextView extends TextView {
    private static final String ELLIPSIS = "...";

    public interface EllipsizeListener {
        void ellipsizeStateChanged(boolean ellipsized);
    }

    private final List<EllipsizeListener> ellipsizeListeners = new ArrayList<EllipsizeListener>();
    private boolean isEllipsized;
    private boolean isStale;
    private boolean programmaticChange;
    private String fullText;
    private int maxLines = -1;
    private float lineSpacingMultiplier = 1.0f;
    private float lineAdditionalVerticalPadding = 0.0f;

    public EllipsizingTextView(Context context) {
        super(context);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void addEllipsizeListener(EllipsizeListener listener) {
        if (listener == null) {
            throw new NullPointerException();
        }
        ellipsizeListeners.add(listener);
    }

    public void removeEllipsizeListener(EllipsizeListener listener) {
        ellipsizeListeners.remove(listener);
    }

    public boolean isEllipsized() {
        return isEllipsized;
    }

    @Override
    public void setMaxLines(int maxLines) {
        super.setMaxLines(maxLines);
        this.maxLines = maxLines;
        isStale = true;
    }

    public int getMaxLines() {
        return maxLines;
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        this.lineAdditionalVerticalPadding = add;
        this.lineSpacingMultiplier = mult;
        super.setLineSpacing(add, mult);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start, int before, int after) {
        super.onTextChanged(text, start, before, after);
        if (!programmaticChange) {
            fullText = text.toString();
            isStale = true;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (isStale) {
            super.setEllipsize(null);
            resetText();
        }
        super.onDraw(canvas);
    }

    private void resetText() {
        int maxLines = getMaxLines();
        String workingText = fullText;
        boolean ellipsized = false;
        if (maxLines != -1) {
            Layout layout = createWorkingLayout(workingText);
            if (layout.getLineCount() > maxLines) {
                workingText = fullText.substring(0, layout.getLineEnd(maxLines - 1)).trim();
                while (createWorkingLayout(workingText + ELLIPSIS).getLineCount() > maxLines) {
                    int lastSpace = workingText.lastIndexOf(' ');
                    if (lastSpace == -1) {
                        break;
                    }
                    workingText = workingText.substring(0, lastSpace);
                }
                workingText = workingText + ELLIPSIS;
                ellipsized = true;
            }
        }
        if (!workingText.equals(getText())) {
            programmaticChange = true;
            try {
                setText(workingText);
            } finally {
                programmaticChange = false;
            }
        }
        isStale = false;
        if (ellipsized != isEllipsized) {
            isEllipsized = ellipsized;
            for (EllipsizeListener listener : ellipsizeListeners) {
                listener.ellipsizeStateChanged(ellipsized);
            }
        }
    }

    private Layout createWorkingLayout(String workingText) {
        return new StaticLayout(workingText, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),
                Alignment.ALIGN_NORMAL, lineSpacingMultiplier, lineAdditionalVerticalPadding, false);
    }

    @Override
    public void setEllipsize(TruncateAt where) {
        // Ellipsize settings are not respected
    }
}

Solution 2

In my app, I had similar problem: 2 line of string and, eventually, add "..." if the string was too long. I used this code in xml file into textview tag:

android:maxLines="2"
android:ellipsize="end"
android:singleLine="false"

Solution 3

Try this, it works for me, I have 4 lines and it adds the "..." to the end of the last/fourth line. Its the same as morale's answer but i have singeLine="false" in there.

<TextView 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:maxLines="4" 
android:ellipsize="marquee" 
android:singleLine="false" 
android:text="Hi make this a very long string that wraps at least 4 lines, seriously make it really really long so it gets cut off at the fourth line not joke.  Just do it!" />

Solution 4

I've run into this problem, too. There's a rather old bug about it that remains unanswered: Bug 2254

Solution 5

I combined the solutions by Micah Hainline, Alex Băluț, and Paul Imhoff to create an ellipsizing multiline TextView that also supports Spanned text.

You only need to set android:ellipsize and android:maxLines.

/*
 * Copyright (C) 2011 Micah Hainline
 * Copyright (C) 2012 Triposo
 * Copyright (C) 2013 Paul Imhoff
 * Copyright (C) 2014 Shahin Yousefi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.support.annotation.NonNull;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.StaticLayout;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class EllipsizingTextView extends TextView {
    private static final CharSequence ELLIPSIS = "\u2026";
    private static final Pattern DEFAULT_END_PUNCTUATION
            = Pattern.compile("[\\.!?,;:\u2026]*$", Pattern.DOTALL);
    private final List<EllipsizeListener> mEllipsizeListeners = new ArrayList<>();
    private EllipsizeStrategy mEllipsizeStrategy;
    private boolean isEllipsized;
    private boolean isStale;
    private boolean programmaticChange;
    private CharSequence mFullText;
    private int mMaxLines;
    private float mLineSpacingMult = 1.0f;
    private float mLineAddVertPad = 0.0f;

    private Pattern mEndPunctPattern;

    public EllipsizingTextView(Context context) {
        this(context, null);
    }


    public EllipsizingTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }


    public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray a = context.obtainStyledAttributes(attrs,
                new int[]{ android.R.attr.maxLines }, defStyle, 0);
        setMaxLines(a.getInt(0, Integer.MAX_VALUE));
        a.recycle();
        setEndPunctuationPattern(DEFAULT_END_PUNCTUATION);
    }

    public void setEndPunctuationPattern(Pattern pattern) {
        mEndPunctPattern = pattern;
    }

    public void addEllipsizeListener(@NonNull EllipsizeListener listener) {
        mEllipsizeListeners.add(listener);
    }

    public void removeEllipsizeListener(EllipsizeListener listener) {
        mEllipsizeListeners.remove(listener);
    }

    public boolean isEllipsized() {
        return isEllipsized;
    }

    @SuppressLint("Override")
    public int getMaxLines() {
        return mMaxLines;
    }

    @Override
    public void setMaxLines(int maxLines) {
        super.setMaxLines(maxLines);
        mMaxLines = maxLines;
        isStale = true;
    }

    public boolean ellipsizingLastFullyVisibleLine() {
        return mMaxLines == Integer.MAX_VALUE;
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        mLineAddVertPad = add;
        mLineSpacingMult = mult;
        super.setLineSpacing(add, mult);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        if (!programmaticChange) {
            mFullText = text;
            isStale = true;
        }
        super.setText(text, type);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (ellipsizingLastFullyVisibleLine()) isStale = true;
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        super.setPadding(left, top, right, bottom);
        if (ellipsizingLastFullyVisibleLine()) isStale = true;
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        if (isStale) resetText();
        super.onDraw(canvas);
    }

    private void resetText() {
        int maxLines = getMaxLines();
        CharSequence workingText = mFullText;
        boolean ellipsized = false;

        if (maxLines != -1) {
            if (mEllipsizeStrategy == null) setEllipsize(null);
            workingText = mEllipsizeStrategy.processText(mFullText);
            ellipsized = !mEllipsizeStrategy.isInLayout(mFullText);
        }

        if (!workingText.equals(getText())) {
            programmaticChange = true;
            try {
                setText(workingText);
            } finally {
                programmaticChange = false;
            }
        }

        isStale = false;
        if (ellipsized != isEllipsized) {
            isEllipsized = ellipsized;
            for (EllipsizeListener listener : mEllipsizeListeners) {
                listener.ellipsizeStateChanged(ellipsized);
            }
        }
    }

    @Override
    public void setEllipsize(TruncateAt where) {
        if (where == null) {
            mEllipsizeStrategy = new EllipsizeNoneStrategy();
            return;
        }

        switch (where) {
            case END:
                mEllipsizeStrategy = new EllipsizeEndStrategy();
                break;
            case START:
                mEllipsizeStrategy = new EllipsizeStartStrategy();
                break;
            case MIDDLE:
                mEllipsizeStrategy = new EllipsizeMiddleStrategy();
                break;
            case MARQUEE:
                super.setEllipsize(where);
                isStale = false;
            default:
                mEllipsizeStrategy = new EllipsizeNoneStrategy();
                break;
        }
    }

    public interface EllipsizeListener {
        void ellipsizeStateChanged(boolean ellipsized);
    }

    private abstract class EllipsizeStrategy {
        public CharSequence processText(CharSequence text) {
            return !isInLayout(text) ? createEllipsizedText(text) : text;
        }

        public boolean isInLayout(CharSequence text) {
            Layout layout = createWorkingLayout(text);
            return layout.getLineCount() <= getLinesCount();
        }

        protected Layout createWorkingLayout(CharSequence workingText) {
            return new StaticLayout(workingText, getPaint(),
                    getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
                    Alignment.ALIGN_NORMAL, mLineSpacingMult,
                    mLineAddVertPad, false /* includepad */);
        }

        protected int getLinesCount() {
            if (ellipsizingLastFullyVisibleLine()) {
                int fullyVisibleLinesCount = getFullyVisibleLinesCount();
                return fullyVisibleLinesCount == -1 ? 1 : fullyVisibleLinesCount;
            } else {
                return mMaxLines;
            }
        }

        protected int getFullyVisibleLinesCount() {
            Layout layout = createWorkingLayout("");
            int height = getHeight() - getCompoundPaddingTop() - getCompoundPaddingBottom();
            int lineHeight = layout.getLineBottom(0);
            return height / lineHeight;
        }

        protected abstract CharSequence createEllipsizedText(CharSequence fullText);
    }

    private class EllipsizeNoneStrategy extends EllipsizeStrategy {
        @Override
        protected CharSequence createEllipsizedText(CharSequence fullText) {
            return fullText;
        }
    }

    private class EllipsizeEndStrategy extends EllipsizeStrategy {
        @Override
        protected CharSequence createEllipsizedText(CharSequence fullText) {
            Layout layout = createWorkingLayout(fullText);
            int cutOffIndex = layout.getLineEnd(mMaxLines - 1);
            int textLength = fullText.length();
            int cutOffLength = textLength - cutOffIndex;
            if (cutOffLength < ELLIPSIS.length()) cutOffLength = ELLIPSIS.length();
            String workingText = TextUtils.substring(fullText, 0, textLength - cutOffLength).trim();
            String strippedText = stripEndPunctuation(workingText);

            while (!isInLayout(strippedText + ELLIPSIS)) {
                int lastSpace = workingText.lastIndexOf(' ');
                if (lastSpace == -1) break;
                workingText = workingText.substring(0, lastSpace).trim();
                strippedText = stripEndPunctuation(workingText);
            }

            workingText = strippedText + ELLIPSIS;
            SpannableStringBuilder dest = new SpannableStringBuilder(workingText);

            if (fullText instanceof Spanned) {
                TextUtils.copySpansFrom((Spanned) fullText, 0, workingText.length(), null, dest, 0);
            }
            return dest;
        }

        public String stripEndPunctuation(CharSequence workingText) {
            return mEndPunctPattern.matcher(workingText).replaceFirst("");
        }
    }

    private class EllipsizeStartStrategy extends EllipsizeStrategy {
        @Override
        protected CharSequence createEllipsizedText(CharSequence fullText) {
            Layout layout = createWorkingLayout(fullText);
            int cutOffIndex = layout.getLineEnd(mMaxLines - 1);
            int textLength = fullText.length();
            int cutOffLength = textLength - cutOffIndex;
            if (cutOffLength < ELLIPSIS.length()) cutOffLength = ELLIPSIS.length();
            String workingText = TextUtils.substring(fullText, cutOffLength, textLength).trim();

            while (!isInLayout(ELLIPSIS + workingText)) {
                int firstSpace = workingText.indexOf(' ');
                if (firstSpace == -1) break;
                workingText = workingText.substring(firstSpace, workingText.length()).trim();
            }

            workingText = ELLIPSIS + workingText;
            SpannableStringBuilder dest = new SpannableStringBuilder(workingText);

            if (fullText instanceof Spanned) {
                TextUtils.copySpansFrom((Spanned) fullText, textLength - workingText.length(),
                        textLength, null, dest, 0);
            }
            return dest;
        }
    }

    private class EllipsizeMiddleStrategy extends EllipsizeStrategy {
        @Override
        protected CharSequence createEllipsizedText(CharSequence fullText) {
            Layout layout = createWorkingLayout(fullText);
            int cutOffIndex = layout.getLineEnd(mMaxLines - 1);
            int textLength = fullText.length();
            int cutOffLength = textLength - cutOffIndex;
            if (cutOffLength < ELLIPSIS.length()) cutOffLength = ELLIPSIS.length();
            cutOffLength += cutOffIndex % 2;    // Make it even.
            String firstPart = TextUtils.substring(
                    fullText, 0, textLength / 2 - cutOffLength / 2).trim();
            String secondPart = TextUtils.substring(
                    fullText, textLength / 2 + cutOffLength / 2, textLength).trim();

            while (!isInLayout(firstPart + ELLIPSIS + secondPart)) {
                int lastSpaceFirstPart = firstPart.lastIndexOf(' ');
                int firstSpaceSecondPart = secondPart.indexOf(' ');
                if (lastSpaceFirstPart == -1 || firstSpaceSecondPart == -1) break;
                firstPart = firstPart.substring(0, lastSpaceFirstPart).trim();
                secondPart = secondPart.substring(firstSpaceSecondPart, secondPart.length()).trim();
            }

            SpannableStringBuilder firstDest = new SpannableStringBuilder(firstPart);
            SpannableStringBuilder secondDest = new SpannableStringBuilder(secondPart);

            if (fullText instanceof Spanned) {
                TextUtils.copySpansFrom((Spanned) fullText, 0, firstPart.length(),
                        null, firstDest, 0);
                TextUtils.copySpansFrom((Spanned) fullText, textLength - secondPart.length(),
                        textLength, null, secondDest, 0);
            }
            return TextUtils.concat(firstDest, ELLIPSIS, secondDest);
        }
    }
}

Complete source: EllipsizingTextView.java

Share:
115,481

Related videos on Youtube

Arutha
Author by

Arutha

Updated on December 13, 2021

Comments

  • Arutha
    Arutha over 2 years

    I need to ellipsize a multi-line textview. My component is large enough to display at least 4 lines with the ellipse, but only 2 lines are displayed. I tried to change the minimum and maximum number of rows of the component but it changes nothing.

    • Cheryl Simon
      Cheryl Simon over 14 years
      Do you have a style or theme that is applied to your TextView, that could be specifying a maximum size?
    • UMAR-MOBITSOLUTIONS
      UMAR-MOBITSOLUTIONS over 13 years
      did you find solution to this problem or not?
    • STeN
      STeN over 12 years
      Hi, after fighting with the problem of having the 2 lines of text (maxLines=2) and three dots at the end of the text (ellipsize=end) I have found that it works on some devices and on some not (I have ~15 devices to test). It works usually on devices with the resolution higher then HVGA (320x480px), but also on some HTC with 240x320px... The only solution is to have a custom TextView as shown below...
    • HannahMitt
      HannahMitt over 9 years
      Mine worked fine after removing "android:textIsSelectable=true"
    • aleb
      aleb almost 9 years
      As Robert Nekic said, there was an Android bug which is now fixed: code.google.com/p/android/issues/detail?id=2254 Would be good to know which is the first Android release where this is fixed.
    • Paul Wintz
      Paul Wintz over 6 years
      For me, android:ellipsize="end" works, but android:ellipsize="middle" does not.
  • Arutha
    Arutha over 14 years
    How to use these ? The text is still truncated to two lines whatever the value that I give them
  • moraes
    moraes over 14 years
    How are you setting it? I think you're missing something but it is hard to guess.
  • Arutha
    Arutha over 14 years
    I used the same settings but my text is always trunked to two lines
  • moraes
    moraes over 14 years
    Eeeks. You are right. I tried that and could not make a 4-line ellipsis. It breaks always at the second line.
  • Lysogen
    Lysogen about 13 years
    Seriously, Try this if you don't think it works it does for me: code <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:maxLines="4" android:ellipsize="marquee" android:singleLine="false" android:text="Hai make this a very long string that wraps at least 4 lines!" />
  • Pzanno
    Pzanno almost 13 years
    This does work, though it should be mentioned that this will no longer add the ellipsis to the end of the last line, but in my opinion this still a good solution to the problem. Also, you will need to use the android:maxLines="4" to limit it to 4 lines.
  • Micah Hainline
    Micah Hainline almost 13 years
    Lysogen, this solution doesn't actually work, at least not for others here. Perhaps you are using a device very different from other people, but as a general solution, this is not effective.
  • pents90
    pents90 almost 13 years
    Thanks for this code, it worked very well. One wrinkle for other users: you will need to explicitly call setMaxLines(int) rather than just setting the property in XML.
  • Diego Tori
    Diego Tori over 12 years
    Actually, it should be very trivial to map out these variables to XML attributes via attrs.xml.
  • Matt K
    Matt K over 12 years
    OP's question was specifically for ellipsis on the end, so it won't work.
  • Matt K
    Matt K over 12 years
    yep, doesn't work. still truncated to two lines. this is frustrating!
  • chengbo
    chengbo over 12 years
    i found a problem if workingText is Chinese. because Chinese doesn't have SPACE, so this code works not perfectly, i have modified some code below, hope will help. while (createWorkingLayout(workingText + ELLIPSIS).getLineCount() > maxLines) { // int lastSpace = workingText.lastIndexOf(' '); // if (lastSpace == -1) { // break; // } // workingText = workingText.substring(0, lastSpace); // 由于我们大多数情况下workingText为中文,所以按照之前的逻辑找空格是不合适的 // 这里改成直接替换最后的字符 workingText = workingText.substring(0, workingText.length() - 1 - 1); }
  • stealthcopter
    stealthcopter over 12 years
    Adding the following into the constructor will allow you to set the maxlines via XML: TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.maxLines }); setMaxLines(a.getInt(0, 2));
  • pgsandstrom
    pgsandstrom over 12 years
    This screws up all the non-string attributes that the TextViews CharSequence holds. For example give the TextView a Spannable with bold text, and the bold is not shown.
  • Jason Robinson
    Jason Robinson over 12 years
    android:singleLine is definitely FALSE by default
  • Nguyen  Minh Binh
    Nguyen Minh Binh about 12 years
    I copy this codes to a demo project and the tesxtview just shows 2 lines.
  • aleb
    aleb about 12 years
    I created an Android library with this component and changed it to be able to show as many lines of text as possible and ellipsize the last one; see github.com/triposo/barone You can see it in action in any of our travel guides, when displaying Suggestions: play.google.com/store/apps/…
  • Cel
    Cel about 12 years
    Works for me on Ice Cream Sandwich tablet!
  • user123321
    user123321 about 12 years
    The comment above works better than the original. However, you should modify the constructors to this: public EllipsizingTextView(Context context, AttributeSet attrs) { this(context, attrs, android.R.attr.textViewStyle); } public EllipsizingTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); super.setEllipsize(null); TypedArray a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.maxLines }); setMaxLines(a.getInt(0, Integer.MAX_VALUE)); a.recycle(); }
  • Kevin Parker
    Kevin Parker almost 12 years
    This answer does not even work... You should try your answers before posting them.
  • moraes
    moraes almost 12 years
    @Kevin: This answer is very old. You should try it with an Android version from January 29, 2010 before saying that it doesn't work and downvoting it.
  • PCoder
    PCoder over 11 years
    Works for me on SII gingerbread. It would be interesting to know more about the devices on which this does not work.
  • Weblance
    Weblance over 11 years
    The bug seems to have been fixed in 4.0.4. It is resolved on Jelly Bean, at least.
  • desgraci
    desgraci over 11 years
    this has a ugly issue, when you put a LinearLayout, with a EllipsizingTextView followed by a TextView, it will only have one.
  • desgraci
    desgraci over 11 years
    the problem is allocated in createWorkingLayout, and it will be showed on the xml editor as IllegalArgumentException: Layout: -40 < 0 at android.text.Layout.<init>(Layout.java:138) at android.text.StaticLayout.<init>(StaticLayout.java:104) StaticLayout.<init>(StaticLayout.java:90) StaticLayout.<init>(StaticLayout.java:68) StaticLayout.<init>(StaticLayout.java:48) at EllipsizingTextView.createWorkingLayout(EllipsizingTextView.‌​java:199) Hope this help...
  • Matt Accola
    Matt Accola over 11 years
    This does work on my Gingerbread device (Droid Bionic), however it has the downside of adding several levels in the stack during the draw phase. This has caused me to receive StackOverflowErrors in some cases...which, admittedly, has more to do with the complexity of my view hierarchy than the component itself.
  • Veer
    Veer over 11 years
    On Galaxy Ace with 2.2, didn't worked. On Nexus S with ICS, it shows 4 lines but no "..." at end.
  • dvs
    dvs over 11 years
    This worked for me on a Droid 3 with 2.3.4 using 2 max lines and a fixed dp height.
  • Paul
    Paul almost 11 years
    Extended the solution to support the other ellipsize types: gist.github.com/imhoff/6245640
  • Stephane Mathis
    Stephane Mathis over 10 years
    Awesome, I was just about to find the original library and translate it myself, thanks !
  • Malachiasz
    Malachiasz about 10 years
    seems much simpler than extending TextView class
  • Nativ
    Nativ about 10 years
    Doesn't works when doing textview.setMovementMethod(LinkMovementMethod.getInstance())
  • Bart Burg
    Bart Burg over 9 years
    And if it doesn't work with this code (in some versions), add the "special sauce" android:scrollHorizontally="true"
  • Bart Burg
    Bart Burg over 9 years
    hooloovoo's answer is much easier and working solution
  • Bart Burg
    Bart Burg over 9 years
    You shouldn't answer a question with an acknowledge
  • Ricardo
    Ricardo over 9 years
    This works for me and is the simplest answer of all.
  • Simas
    Simas over 8 years
    Doesn't work if text set with setText(..., TextView.BufferType.SPANNABLE);.
  • CoolMind
    CoolMind over 8 years
    Thanks, the only working solution (tested several). Wondered, that your rating was 1.
  • GreenROBO
    GreenROBO about 8 years
    @aleb Hey man Thanks a Ton! I just Drag Your EllipsizingTextView class into My Project and it works!
  • Alexey Strakh
    Alexey Strakh almost 8 years
    any news on spannable? @Simas. I've ran into the same issue
  • SalutonMondo
    SalutonMondo over 7 years
    it works on my device with a samsung asm9100 run android 6.0.1 android.
  • javaxian
    javaxian over 6 years
    I can confirm that it's the only clean and working solution, just use the EllipsizingTextView class and forget about hacks.
  • Borja
    Borja almost 6 years
    It's also possible to use it with EditText if needed
  • Shubham Naik
    Shubham Naik almost 6 years
    this is same as setting ellipsize attr in xml.
  • Arundas K V
    Arundas K V over 5 years
    I too had this issue. Android Preview was wrong. In device its fine
  • Jonty800
    Jonty800 over 5 years
    Doesn't work correctly when rendering html (Html.fromHtml)
  • Riddhi Shah
    Riddhi Shah over 4 years
    Hi, your solutions work great! but I want to put Click event on ...ViewMore text. I tried to add clickable span in resetText(). But its not working