试了下网上常见的做法,并不能满足需求,主要一点是,TextView需要在绘制完成后才能获取到一些相关参数,后面发现了一篇博客:
http://blog.csdn.net/gentlemanyc/article/details/49967719
根据博客的教程,能实现了绘制完成后自动返回状态判断,但是还是不能满足需求,发现其中导致的原因是列表的holder机制引起的,上面博客的判断是在绘制完成后返回判断,列表的holder机制导致可能公用同一个TextView导致状态混乱,解决方法就是对每个列表加个字段保存对应的判断状态。如果没有检测过就进行检测:
holder.contentText.setCheckText(bean.Content + "",bean);
holder.contentText.setOnOverLineChangedListener(new CheckOverSizeTextView.OnOverSizeChangedListener() {
@Override
public void onChanged(boolean isOverSize,Object tag) {
if(tag!=null){
NoticeBean bean = (NoticeBean) tag;
if(bean.IsCheck){
if (bean.isOverSize) {
holder.expand.setVisibility(View.VISIBLE);
} else {
holder.expand.setVisibility(View.GONE);
}
}else {
if (isOverSize) {
bean.isOverSize = true;
holder.expand.setVisibility(View.VISIBLE);
} else {
bean.isOverSize = false;
holder.expand.setVisibility(View.GONE);
}
bean.IsCheck = true;
}
}
}
});
手受伤了,手痛,写的有点乱,贴一下修改了的那个类的代码:
import java.lang.reflect.Field;
import android.content.Context;
import android.graphics.Canvas;
import android.text.Layout;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.TextView;
public class CheckOverSizeTextView extends TextView {
protected boolean isOverSize;
protected Object Tag = null;
private OnOverSizeChangedListener changedListener;
public CheckOverSizeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public CheckOverSizeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CheckOverSizeTextView(Context context) {
super(context);
init();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (changedListener != null) {
changedListener.onChanged(checkOverLine(),Tag);
}
}
public void setCheckText(CharSequence text, Object tag) {
this.Tag = tag;
super.setText(text);
}
private void init() {
// invalidate when layout end
getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (changedListener != null) {
changedListener.onChanged(checkOverLine(),Tag);
}
}
});
}
/**
* <p>
* <span style="color: purple;">
* <em>check if the text content has ellipsis </em></span>
* </p>
*
* @return if the text content over maxlines
*/
public boolean checkOverLine() {
int maxLine = 3;
try {
Field field = getClass().getSuperclass().getDeclaredField("mLayout");
field.setAccessible(true);
Layout mLayout = (Layout) field.get(this);
if (mLayout == null)
return false;
isOverSize = mLayout.getEllipsisCount(maxLine - 1) > 0 ? true : false;
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return isOverSize;
}
public boolean isOverSize() {
return isOverSize;
}
public void displayAll() {
setMaxLines(Integer.MAX_VALUE);
setEllipsize(null);
}
public void hide(int maxlines) {
setEllipsize(TruncateAt.END);
setMaxLines(maxlines);
}
// set a listener for callback
public OnOverSizeChangedListener getChangedListener() {
return changedListener;
}
public void setOnOverLineChangedListener(OnOverSizeChangedListener changedListener) {
this.changedListener = changedListener;
}
public interface OnOverSizeChangedListener {
/**
* <span style="color:purple">when invalide,the method will be called
* and tell you whether the content text is over size
*
* @param isOverSize
* whether content text is over size
*/
void onChanged(boolean isOverSize,Object Tag);
};
}