Android setEllipsize在扩展EditText的类上不起作用 [英] Android setEllipsize not working on class that extends EditText

查看:94
本文介绍了Android setEllipsize在扩展EditText的类上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个扩展EditText的类,在这个类上,我试图使文本在长文本时设置setEllipsize.由于某种原因,我的所有小工具都无法正常工作. 看来我可以在文本视图内水平滚动文本... 任何人都可以建议如何使其工作. (到目前为止,我已经尝试了这些功能的许多组合, 那是我在代码中的角色:

I have a class that extends EditText, on this class i'm trying to make the text to set setEllipsize when the text is to long. For some reason all my tryies didn't work. It seems that that i can scroll the text horizontal inside the text view... Can anybody advice how to make it work. (So far i've tryed many combination of those functions and that's my part in the code:

public class LMEditTextAutoSize extends EditText {
private boolean autoSize;

public LMEditTextAutoSize(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mTextSize = getTextSize();
    mMaxTextSize = getTextSize();
}

public LMEditTextAutoSize(Context context, AttributeSet attrs) {
    super(context, attrs);
    mTextSize = getTextSize();
    mMaxTextSize = getTextSize();
}

public LMEditTextAutoSize(Context context) {
    super(context);
    mTextSize = getTextSize();
    mMaxTextSize = getTextSize();
}

public void setAutoSize(boolean autoSize) {
    this.autoSize = autoSize;
    resetTextSize();
}

// Minimum text size for this text view
public static final float MIN_TEXT_SIZE = 50;

// Interface for resize notifications
public interface OnTextResizeListener {
    public void onTextResize(TextView textView, float oldSize, float newSize);
}

// Our ellipse string
private static final String mEllipsis = "...";

// Registered resize listener
private OnTextResizeListener mTextResizeListener;

// Flag for text and/or size changes to force a resize
private boolean mNeedsResize = false;

// Text size that is set from code. This acts as a starting point for resizing
private float mTextSize;

// Temporary upper bounds on the starting text size
private float mMaxTextSize = 0;

// Lower bounds for text size
private float mMinTextSize = MIN_TEXT_SIZE;

// Text view line spacing multiplier
private float mSpacingMult = 1.0f;

// Text view additional line spacing
private float mSpacingAdd = 0.0f;

// Add ellipsis to text that overflows at the smallest text size
private boolean mAddEllipsis = true;

private int widthLimit;

private int heightLimit;

/**
 * When text changes, set the force resize flag to true and reset the text size.
 */
@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
    mNeedsResize = true;
    // Since this view may be reused, it is good to reset the text size
    resetTextSize();

}

/**
 * If the text view size changed, set the force resize flag to true
 */
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (w != oldw || h != oldh) {
        mNeedsResize = true;
    }
}

/**
 * Register listener to receive resize notifications
 * 
 * @param listener
 */
public void setOnResizeListener(OnTextResizeListener listener) {
    mTextResizeListener = listener;
}

/**
 * Override the set text size to update our internal reference values
 */
@Override
public void setTextSize(float size) {
    super.setTextSize(size);
    mTextSize = getTextSize();
}

/**
 * Override the set text size to update our internal reference values
 */
@Override
public void setTextSize(int unit, float size) {
    super.setTextSize(unit, size);
    mTextSize = getTextSize();
}

/**
 * Override the set line spacing to update our internal reference values
 */
@Override
public void setLineSpacing(float add, float mult) {
    super.setLineSpacing(add, mult);
    mSpacingMult = mult;
    mSpacingAdd = add;
}

/**
 * Set the upper text size limit and invalidate the view
 * 
 * @param maxTextSize
 */
public void setMaxTextSize(float maxTextSize) {
    mMaxTextSize = maxTextSize;
    requestLayout();
    invalidate();
}

/**
 * Return upper text size limit
 * 
 * @return
 */
public float getMaxTextSize() {
    return mMaxTextSize;
}

/**
 * Set the lower text size limit and invalidate the view
 * 
 * @param minTextSize
 */
public void setMinTextSize(float minTextSize) {
    mMinTextSize = minTextSize;
    requestLayout();
    invalidate();
}

/**
 * Return lower text size limit
 * 
 * @return
 */
public float getMinTextSize() {
    return mMinTextSize;
}

/**
 * Set flag to add ellipsis to text that overflows at the smallest text size
 * 
 * @param addEllipsis
 */
public void setAddEllipsis(boolean addEllipsis) {
    mAddEllipsis = addEllipsis;
}

/**
 * Return flag to add ellipsis to text that overflows at the smallest text size
 * 
 * @return
 */
public boolean getAddEllipsis() {
    return mAddEllipsis;
}

/**
 * Reset the text to the original size
 */
public void resetTextSize() {
    if (autoSize) {
        if (mTextSize > 0) {
            super.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMaxTextSize);
            mTextSize = mMaxTextSize;
        }
    }
}

/**
 * Resize text after measuring
 */
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    if (changed || mNeedsResize) {
        widthLimit = (right - left) - getCompoundPaddingLeft() - getCompoundPaddingRight();
        heightLimit = (bottom - top) - getCompoundPaddingBottom() - getCompoundPaddingTop();
        resizeText(widthLimit, heightLimit);
    }
    super.onLayout(changed, left, top, right, bottom);
}

/**
 * Resize the text size with specified width and height
 * 
 * @param width
 * @param height
 */
public void resizeText(int width, int height) {
    if (autoSize) {
        CharSequence text = getText();
        int oneLineWidth = width;
        int lineCount = getLineCount();
        int minTextHeight = getTextHeight("oo", getPaint(), width, mMinTextSize);
        int maxLineInHeight = height / minTextHeight;
        lineCount = lineCount > maxLineInHeight ? maxLineInHeight : lineCount;
        if (lineCount > 1) {
            width = width * lineCount;
        }
        // Do not resize if the view does not have dimensions or there is no text
        if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
            return;
        }

        // Get the text view's paint object
        TextPaint textPaint = getPaint();

        // Store the current text size
        float oldTextSize = textPaint.getTextSize();
        // If there is a max text size set, use the lesser of that and the default text size
        float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

        // Get the required text height
        int textHeight = getTextHeight(text, textPaint, width, targetTextSize);

        // Until we either fit within our text view or we had reached our min text size, incrementally try smaller sizes
        while (textHeight > height && targetTextSize > mMinTextSize) {
            targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
            textHeight = getTextHeight(text, textPaint, width, targetTextSize);
        }
        TextPaint paintCopy = new TextPaint(textPaint);
        paintCopy.setTextSize(targetTextSize);
        float textWidte = paintCopy.measureText(text, 0, text.length());
        while (textWidte > width && targetTextSize > mMinTextSize) {
            targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
            paintCopy.setTextSize(targetTextSize);
            textWidte = paintCopy.measureText(text, 0, text.length());
        }

        if (lineCount > 1) {
            int textHeightforLine = getTextHeight(text, textPaint, oneLineWidth, targetTextSize);
            while (textHeightforLine > height && targetTextSize > mMinTextSize) {
                targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
                textHeightforLine = getTextHeight(text, textPaint, oneLineWidth, targetTextSize);
            }
        }

        // If we had reached our minimum text size and still don't fit, append an ellipsis
        if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
            // Draw using a static layout
            // modified: use a copy of TextPaint for measuring
            TextPaint paint = new TextPaint(textPaint);
            paint.setTextSize(mMinTextSize);
            // Draw using a static layout
            StaticLayout layout = new StaticLayout(text, paint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
            // Check that we have a least one line of rendered text
            if (layout.getLineCount() > 0) {
                // Since the line at the specific vertical position would be cut off,
                // we must trim up to the previous line
                int lastLine = layout.getLineForVertical(height) - 1;
                // If the text would not even fit on a single line, clear it
                if (lastLine < 0) {
                    setText("");
                }
                // Otherwise, trim to the previous line and add an ellipsis
                else {
                    int start = layout.getLineStart(lastLine);
                    int end = layout.getLineEnd(lastLine);
                    float lineWidth = layout.getLineWidth(lastLine);
                    float ellipseWidth = textPaint.measureText(mEllipsis);

                    // Trim characters off until we have enough room to draw the ellipsis
                    while (width < lineWidth + ellipseWidth) {
                        lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
                    }
                    if (end != 0) {
                        setInputType(InputType.TYPE_CLASS_TEXT);
                        setSingleLine(true);
                        setLines(1);
                        setMaxLines(1);
                        setEllipsize(TextUtils.TruncateAt.END);
                        setSelected(true);
                        setText(text);
                    }
                }
            }

        }

        // Some devices try to auto adjust line spacing, so force default line spacing
        // and invalidate the layout as a side effect
        setTextSize(TypedValue.COMPLEX_UNIT_PX, targetTextSize);
        setLineSpacing(mSpacingAdd, mSpacingMult);

        // Notify the listener if registered
        if (mTextResizeListener != null) {
            mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
        }

        // Reset force resize flag
        mNeedsResize = false;
    }
}

// Set the text size of the text paint object and use a static layout to render text off screen before measuring
private int getTextHeight(CharSequence source, TextPaint paint, int width, float textSize) {
    TextPaint paintCopy = new TextPaint(paint);
    paintCopy.setTextSize(textSize);
    StaticLayout layout = new StaticLayout(source, paintCopy, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, true);
    return layout.getHeight();
}

}

推荐答案

删除setHorizo​​ntallyScrolling(true),它与setEllipsize(TextUtils.TruncateAt.END)矛盾.有关每个功能,请参阅android文档 https://developer.android.com/reference/android/widget/TextView.html

remove setHorizontallyScrolling(true) it is contradicting with setEllipsize(TextUtils.TruncateAt.END); Refer to the android doc for each ones function https://developer.android.com/reference/android/widget/TextView.html

这篇关于Android setEllipsize在扩展EditText的类上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆