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

    xiaoxiao2025-11-11  6

    先看一下实现效果:

    还不错吧,在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参数,防止出现计算的结果与实际显示的结果不一样

    转载请注明原文地址: https://ju.6miu.com/read-1304068.html
    最新回复(0)