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