Android 查看更多 TextView实现

来源:互联网 发布:sqlserver over函数 编辑:程序博客网 时间:2024/05/22 13:05

在公司开发过程中,需要用到固定行数的展开查看更多的控件,在网上找了好久,都没有找到,于是花了半天时间实现了一个,在此做下记录,主要有几个关键的地方:

private Layout makeTextLayout(String text) {        return new StaticLayout(text, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),                Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);    }

生成StaticLayout 对象,通过它就可以知道有多少行和每一行最后及最前一位字符对应的文本Sring的下标,通过对它进行裁剪,即可实现固定显示多少行。

完整代码如下:


/** * 固定行数展开收缩控件 * Created by evan on 2016/3/3. */public class FolderTextView extends TextView{    private static final String ELLIPSIS="...";    private static final String FOLD_TEXT = "收缩";    private static final String UNFOLD_TEXT = "查看详情";    /**     * 收缩状态     */    private boolean isFold = false;    /**     * 绘制,防止重复进行绘制     */    private boolean isDrawed = false;    /**     * 内部绘制     */    private boolean isInner = false;    /**     * 折叠行数     */    private int foldLine;    /**     * 全文本     */    private String fullText;    private float mSpacingMult = 1.0f;    private float mSpacingAdd = 0.0f;    public FolderTextView(Context context) {        this(context, null);    }    public FolderTextView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public FolderTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        TypedArray a = context.obtainStyledAttributes(R.styleable.FolderTextView);        foldLine = a.getInt(R.styleable.FolderTextView_foldline, 3);        a.recycle();    }    /**     * 不更新全文本下,进行展开和收缩操作     * @param text     */    private void setUpdateText(CharSequence text){        isInner = true;        setText(text);    }    @Override    public void setText(CharSequence text, BufferType type) {        if(TextUtils.isEmpty(fullText) || !isInner){            isDrawed = false;            fullText = String.valueOf(text);        }        super.setText(text, type);    }    @Override    public void setLineSpacing(float add, float mult) {        mSpacingAdd = add;        mSpacingMult = mult;        super.setLineSpacing(add, mult);    }    public int getFoldLine() {        return foldLine;    }    public void setFoldLine(int foldLine) {        this.foldLine = foldLine;    }    private Layout makeTextLayout(String text) {        return new StaticLayout(text, getPaint(), getWidth() - getPaddingLeft() - getPaddingRight(),                Layout.Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);    }    @Override    protected void onDraw(Canvas canvas) {        if(!isDrawed){            resetText();        }        super.onDraw(canvas);        isDrawed = true;        isInner = false;    }    private void resetText() {        String spanText = fullText;        SpannableString spanStr;        //收缩状态        if(isFold){            spanStr = createUnFoldSpan(spanText);        }else{ //展开状态            spanStr = createFoldSpan(spanText);        }        setUpdateText(spanStr);        setMovementMethod(LinkMovementMethod.getInstance());    }    /**     * 创建展开状态下的Span     * @param text 源文本     * @return     */    private SpannableString createUnFoldSpan(String text) {        String destStr = text + FOLD_TEXT;        int start = destStr.length() - FOLD_TEXT.length();        int end = destStr.length();        SpannableString spanStr = new SpannableString(destStr);        spanStr.setSpan(clickSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);        return spanStr;    }    /**     * 创建收缩状态下的Span     * @param text     * @return     */    private SpannableString createFoldSpan(String text) {        String destStr = tailorText(text);        int start = destStr.length() - UNFOLD_TEXT.length();        int end = destStr.length();        SpannableString spanStr = new SpannableString(destStr);        spanStr.setSpan(clickSpan,start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);        return spanStr;    }    /**     * 裁剪文本至固定行数     * @param text 源文本     * @return     */    private String tailorText(String text){        String destStr = text + ELLIPSIS + UNFOLD_TEXT;        Layout layout = makeTextLayout(destStr);        //如果行数大于固定行数        if(layout.getLineCount() > getFoldLine()){            int index = layout.getLineEnd(getFoldLine());            if(text.length() < index){                index = text.length();            }            String subText = text.substring(0, index-1); //从最后一位逐渐试错至固定行数            return tailorText(subText);        }else{            return destStr;        }    }    ClickableSpan clickSpan = new ClickableSpan() {        @Override        public void onClick(View widget) {            isFold = !isFold;            isDrawed = false;            invalidate();        }        @Override        public void updateDrawState(TextPaint ds) {            ds.setColor(ds.linkColor);        }    };}


其中定义了一个属性foldLine,用于设置收缩行数

定义到attrs.xml中

<declare-styleable name="FolderTextView">        <attr name="foldline" format="integer" />    </declare-styleable>


至此,展开查看更多和收起的功能实现 ,使用和TextView的使用方法一致,这里就不介绍了。


1 0
原创粉丝点击