原有思路:
-
View.Post() 方式
说明:将处理添加到主线程队列中,等待处理,会有显示慢的问题,由于View的复用,当列表滑动后,就不能正确返回相关值了.
-
getViewTreeObserver().addOnGlobalLayoutListener()
说明:添加全局View 变化监听,会被多次调用,并且在列表滑动过程中,跟View.Post() 有相同的问题.
新思路
- onDraw()
- onLayout()
- onMeasure() 中进行获取对应TextView 的getLineCount()
View 的绘制过程为 onMeasure()->onLayout()->onDraw()
所以将处理逻辑放置到 onMeasure()中.
说明:
- 封装 容器 CommendContainerView,继承 RelativeLayout
- 重写 onMeasure()方法,当 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 执行完后, 容器已经知道了所有子View 的相关尺寸, 这个时候 可以去进行判断了.并且不会有延时问题.
- 进行逻辑判断后,调用 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 对子View 再进行一次测量.保证显示逻辑.
- 针对于 用户操作过的 View, 将状态进行缓存.
下面直接上代码:
public class CommendContainerView extends RelativeLayout {
private TextView mCommendTextView;
private TextView mCommendFun;
private CommendShowFunListener mListener;
private boolean mFlag = true;
private int mLinesLimit = 1;
private Boolean mShowAll;
private int mPos;
public CommendContainerView(Context context) {
this(context, null);
}
public CommendContainerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CommendContainerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs, defStyleAttr);
}
//初始化布局~
private void initView(Context context, AttributeSet attrs, int defStyleAttr) {
inflate(context, R.layout.view_commend_container, this);
mCommendTextView = findViewById(R.id.commend_ctv_commend);
mCommendFun = findViewById(R.id.commend_tv_fun);
mCommendFun.setOnClickListener(onClickListener);
}
public void setCommendInfo(CharSequence text, Boolean showAll, int pos) {
mShowAll = showAll;
mPos = pos;
if (null != mShowAll) {
mFlag = true;
mCommendFun.setVisibility(VISIBLE);
if (mShowAll) {
mCommendFun.setText(R.string.desc_shrinkup);
mCommendTextView.setMaxLines(Integer.MAX_VALUE);
} else {
mCommendFun.setText(R.string.desc_spread);
mCommendTextView.setMaxLines(mLinesLimit);
}
mCommendTextView.setText(text);
} else {
mFlag = false;
mCommendFun.setVisibility(GONE);
mCommendTextView.setMaxLines(Integer.MAX_VALUE);
mCommendTextView.setText(text);
}
}
private OnClickListener onClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
mCommendFun.setVisibility(VISIBLE);
mFlag = true;
if (null == mShowAll || !mShowAll) {
mCommendTextView.setMaxLines(Integer.MAX_VALUE);
mCommendFun.setText(R.string.desc_shrinkup);
mShowAll = true;
} else {
mCommendTextView.setMaxLines(mLinesLimit);
mCommendFun.setText(R.string.desc_spread);
mShowAll = false;
}
if (null != mListener) {
mListener.onShowStatusChange(mPos, mShowAll);
}
}
};
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mFlag) {
mFlag = true;
if (mCommendTextView.getLineCount() > mLinesLimit) {
//超过行数~
mCommendFun.setVisibility(VISIBLE);
mCommendFun.setText(R.string.desc_spread);
mCommendTextView.setMaxLines(mLinesLimit);
} else {
mCommendFun.setVisibility(GONE);
mCommendTextView.setMaxLines(Integer.MAX_VALUE);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setCommendShowFunListener(CommendShowFunListener listener) {
this.mListener = listener;
}
public void setLinesLimit(int limit) {
this.mLinesLimit = limit;
}
interface CommendShowFunListener {
void onShowStatusChange(int pos, boolean showAll);
}
}
网友评论