android ellipsize multiline textview android ellipsize multiline textview android android

android ellipsize multiline textview


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    }}


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"


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!" />