自定义逻辑实现可折叠TextView
在开发的过程中,总会遇到要制作信息界面。信息界面中简介的设计总会涉及到要点击展开过长的简介,本文就是介绍如何用一种简便的方法设计出好看的可折叠TextView。
效果演示

Java逻辑
introduce.post(new Runnable() {
@Override
public void run() {
// 监听点击折叠TextView事件
if (introduce.getLineCount() > maxLines) {
introduce.setOnClickListener(mListener);
more.setOnClickListener(mListener);
}
// 判断要不要显示 更多箭头
more.setVisibility(holder.introduce.getLineCount() > maxLines ? View.VISIBLE : View.GONE);
}
});
其中maxLines是在xml文件中TextView设置的最大行数,超过这个行数后便不会显示。introduce是TextView控件,more是TextView控件右下角的那个更多小箭头。这段代码用于判断是否需要添加那个小箭头,以及是否需要给TextView添加点击监听器。
值得注意的是这段代码必须写在TextView控件的Post方法中,原因是如果直接写在OnCrate方法中的话,因为那个时候TextView还没有渲染完成,调用TextView的getLineCount()方法返回的始终是0,就会导致结果出错。
监听器代码如下:
final View.OnClickListener mListener = new View.OnClickListener() {
boolean isExpand;
@Override
public void onClick(View v) {
isExpand = !isExpand;
introduce.clearAnimation();
final float deltaHeight;
final float startHeight = introduce.getHeight();
int duration = 350;
if (isExpand) {
// 折叠动画
deltaHeight = introduce.getLineHeight() * introduce.getLineCount() - startHeight;
RotateAnimation animation = new RotateAnimation(0, 180,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
animation.setDuration(duration);
animation.setFillAfter(true);
holder.more.startAnimation(animation);
} else {
// 展开动画
deltaHeight = introduce.getLineHeight() * maxLines - startHeight;
RotateAnimation animation = new RotateAnimation(180, 0,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
animation.setDuration(duration);
animation.setFillAfter(true);
more.startAnimation(animation);
}
Animation animation = new Animation() {
protected void applyTransformation(float interpolatedTime, Transformation t) {
//根据ImageView旋转动画的百分比来显示TextView高度,达到动画效果
introduce.setHeight((int) (startHeight + deltaHeight * interpolatedTime));
}
};
animation.setDuration(duration);
introduce.startAnimation(animation);
}
};
实现方法主要是通过计算TextView目前高度以及展开后需要到达的高度,配合右下角更多图片旋转的速度利用setHeight对现有的TextView进行拓展。
至此就可以实现演示中的效果了。
待解决问题
因为TextView换行符\n在不同手机上显示的行高是不一样的,这个换行符会导致TextView自身的getHeight不等于getLineCount * getLineHeight所以在某些手机上显示可能会有问题,例如展开后并不能完全显示全部的内容。

