ExpandLongTextView 设置了maxLines后在TextView末尾加上自定义的ellipsize

来源:互联网 发布:社会与经济发展数据库 编辑:程序博客网 时间:2024/06/10 08:45

先看一下实现效果:
最后的显示效果图(设计图)

还不错吧,在TextView末尾加上了自定义的ClickableSpan,点击的话可以全部显示内容。

实现思路,通过预创建StaticLayout,截取我们要显示的6行内容,

循环:    判断 截取的内容 + append的内容 是否大于6行,        是:截取的内容从末尾 -1,continue        否:得到最后截取的内容如果截取了,则显示 截取的内容 + “...” + append的内容

核心代码:
继承TextView的ExpandLongTextView

/** * Created by 祥祥 on 2016/8/15. */public class ExpandLongTextView extends TextView {    private String originText;    private int initWidth = 0;    private int mMaxLines = 6;    public ExpandLongTextView(Context context) {        super(context);    }    public ExpandLongTextView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public ExpandLongTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private SpannableString ELLIPSIS = null;    private void init(){        String content = "显示全部";        ELLIPSIS = new SpannableString(content);        ButtonSpan span = new ButtonSpan(getContext(), new View.OnClickListener(){            @Override            public void onClick(View v) {                setMaxLines(Integer.MAX_VALUE);                setText(originText);            }        }, R.color.sanjieke_yellow);        ELLIPSIS.setSpan(span, 0, content.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);    }    @Override    public void setMaxLines(int maxLines) {        this.mMaxLines = maxLines;        super.setMaxLines(maxLines);    }    /**     * 初始化TextView的宽度     * @param width     */    public void initWidth(int width){        initWidth = width;    }    public void setExpandText(CharSequence text) {        if (null == ELLIPSIS){            init();        }        originText = text.toString();        boolean appendShowAll = false;        int maxLines = 0;        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {            maxLines = getMaxLines();        } else{            maxLines = mMaxLines;        }        String workingText = new StringBuilder(originText).toString();        if (maxLines != -1) {            Layout layout = createWorkingLayout(workingText);            if (layout.getLineCount() > maxLines) {                //获取一行显示字符个数,然后截取字符串数                workingText = originText.substring(0, layout.getLineEnd(maxLines - 1)).trim();                String showText = originText.substring(0, layout.getLineEnd(maxLines - 1)).trim() + "..." + ELLIPSIS;                Layout layout2 = createWorkingLayout(showText);                while (layout2.getLineCount() > maxLines) {                    int lastSpace = workingText.length()-1;                    if (lastSpace == -1) {                        break;                    }                    workingText = workingText.substring(0, lastSpace);                    layout2 = createWorkingLayout(workingText + "..." + ELLIPSIS);                }                appendShowAll = true;                workingText = workingText + "...";            }        }        setText(workingText);        if (appendShowAll) {            // 必须使用append,不能在上面使用+连接,否则spannable会无效            append(ELLIPSIS);                  setMovementMethod(LinkMovementMethod.getInstance());        }    }    //返回textview的显示区域的layout,该textview的layout并不会显示出来,只是用其宽度来比较要显示的文字是否过长    private Layout createWorkingLayout(String workingText) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {            return StaticLayout.Builder.obtain(workingText, 0, workingText.length(), getPaint(), initWidth - getPaddingLeft() - getPaddingRight())                    .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier())                    .setAlignment(Layout.Alignment.ALIGN_NORMAL)                    // 注意,在textview里需要设置这两个参数,否则显示会不正常                    .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)                    .build();        } else{            return StaticLayout.Builder.obtain(workingText, 0, workingText.length(), getPaint(), initWidth - getPaddingLeft() - getPaddingRight())                    .setLineSpacing(lineSpaceExtra, 1.0f)                    .setAlignment(Layout.Alignment.ALIGN_NORMAL)                    // 注意,在textview里需要设置这两个参数,否则显示会不正常                    .setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY)                    .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL)                    .build();        }    }}

ButtonSpan:

/** * Created by 祥祥 on 2016/7/14. */public class ButtonSpan extends ClickableSpan {    View.OnClickListener onClickListener;    private Context context;    private int colorId;    public ButtonSpan(Context context, View.OnClickListener onClickListener) {        this(context, onClickListener, R.color.span_button_color);    }    public ButtonSpan(Context context, View.OnClickListener onClickListener, int colorId){        this.onClickListener = onClickListener;        this.context = context;        this.colorId = colorId;    }    @Override    public void updateDrawState(TextPaint ds) {        ds.setColor(context.getResources().getColor(colorId));        ds.setUnderlineText(false);    }    @Override    public void onClick(View widget) {        if (onClickListener != null) {            onClickListener.onClick(widget);        }    }}

使用方法:

tv_content = (ExpandLongTextView) itemView.findViewById(R.id.tv_comment_content);// 必须要计算并初始化宽度tv_content.initWidth(ViewUtil.getWindowWidth(context) - ViewUtil.dp2px(context, 80));// 设置最大行数(因为sdk14及以下无法调用获取最大行数的方法,所以加了这个)tv_content.setMaxLines(6);// 调用这个方法进行初始化设置文本内容tv_content.setExpandText((String) getDataByPosition(position));

目前设个封装效果不是很好,而且使用起来也略微麻烦。你如果有更好的建议,可以在评论区提一下。

参考博客http://blog.csdn.net/henry121212/article/details/7615660

修改:修改了createWorkingLayout方法,设置setBreakStrategy参数,防止出现计算的结果与实际显示的结果不一样

0 0
原创粉丝点击