写在前面
文本过长的展开和折叠,我本来的思路是通过TextView的 getLineCount() 方法判断文本内容的行数,然后这样进行展开或折叠。实际上,调用这个方法,在视图没有完全绘制时,getLineCount得到的行数永远是0。这个问题,可以使用观察者去监听来解决,下面是具体操作。
设置展示的最大行数
按照PM的要求,把最大行数设置为5行:
<!-- 内容 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:minHeight="30dp"
android:textColor="@color/menuFont"
android:textSize="16sp"
android:maxLines="5"
android:ellipsize="end" />
<!-- 展开或收起 -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:text="@string/pack_down"
android:textColor="@color/colorPrimaryDark"
android:textSize="16sp"
android:visibility="gone" />
通过 android:maxLines=“5”
android:ellipsize=“end”,这些大家都知道,就不说了。
创建观察者
在Adapter中创建负责内容展示的TextView的观察者
// 创建观察者,dynamicContent是负责内容展示的TextView
ViewTreeObserver viewTreeObserver = holder.dynamicContent.getViewTreeObserver();
然后通过观察者去监听,其中为了避免观察者监听重复调用,所以需要移除
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 避免Observer监听重复调用,移除掉
ViewTreeObserver observer = holder.dynamicContent.getViewTreeObserver();
observer.removeOnGlobalLayoutListener(this);
// 在这里编写你需要的收起或展开的代码
code...
}
});
然后,,我通过getLineCount 方法在上面的监听中来判断 是否需要展开或收起操作
if (holder.dynamicContent.getLineCount() >= 5) {
holder.packTV.setVisibility(View.VISIBLE);
// 全文/收起
holder.packTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPack){
// 当前为默认状态False(内容处于收起状态),点击后文本按钮变成收起(内容处于展开状态)
holder.packTV.setText(R.string.pack_up);
isPack = true;
holder.dynamicContent.setMaxLines(50);
} else {
// 点击后文本按钮变成展开(内容处于收起状态)
holder.packTV.setText(R.string.pack_down);
isPack = false;
holder.dynamicContent.setMaxLines(5);
}
}
});
} else {
holder.packTV.setVisibility(View.GONE);
}
上面我设置的展开后的最大行数是50行。
这样通过观察者监听,就可以实现展开或收起的功能了。
还有 isPack 是用来标记当前是展开还是收起状态的。
// 判断展开或收起
private boolean isPack = false;
贴上完整的代码块
// 获取TextView的文本内容行数,大于5行就显示全文展示,因为在View没有完全绘制的时候,所有的TextView的文本长度都是0,使用观察者去监听可以解决
ViewTreeObserver viewTreeObserver = holder.dynamicContent.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// 避免Observer监听重复调用,移除掉
ViewTreeObserver observer = holder.dynamicContent.getViewTreeObserver();
observer.removeOnGlobalLayoutListener(this);
if (holder.dynamicContent.getLineCount() >= 5) {
holder.packTV.setVisibility(View.VISIBLE);
// 全文/收起
holder.packTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPack){
// 当前为默认状态False(内容处于收起状态),点击后文本按钮变成收起(内容处于展开状态)
holder.packTV.setText(R.string.pack_up);
isPack = true;
holder.dynamicContent.setMaxLines(50);
} else {
// 点击后文本按钮变成展开(内容处于收起状态)
holder.packTV.setText(R.string.pack_down);
isPack = false;
holder.dynamicContent.setMaxLines(5);
}
}
});
} else {
holder.packTV.setVisibility(View.GONE);
}
}
});
写在最后
项目快要结束了,记录一下过程中遇到的问题,关于这个仿朋友圈的展开和收起功能,很久之前做的了,都忘记当时参考哪些大神的博客了,参考了网上的一些博客、文章,可能有相似的地方,抱歉。