全文和收起功能实现文档
=====================================
功能描述
--------
在朋友圈列表(DiscoveryFragment)中,当文本内容超过4行时,自动显示"全文"按钮。
点击"全文"按钮后,展开显示全部内容,按钮文字变为"收起"。
点击"收起"按钮后,文本收起为4行,按钮文字变为"全文"。
如果文本不超过4行,则不显示展开/收起按钮。
实现位置
--------
1. 布局文件:uikit/src/main/res/layout/adapter_pengyouquan_item.xml
2. 代码文件:app/src/main/java/com/xunpaisoft/social/im/main/DiscoveryFragment.java
修改详情
--------
一、布局文件修改(adapter_pengyouquan_item.xml)
------------------------------------------------
修改前:
修改后:
说明:
- 将原来的单个TextView包装在LinearLayout中
- 添加了tv_ada_expand作为"全文/收起"按钮
- tv_ada_content设置maxLines="4"和ellipsize="end",默认显示4行
- tv_ada_expand默认隐藏(visibility="gone")
二、代码文件修改(DiscoveryFragment.java)
------------------------------------------
修改位置:bindView方法中,处理tv_ada_content的部分
核心逻辑:
1. 获取控件引用
TextView tvContent = (TextView) holder.getView(cn.wildfire.chat.kit.R.id.tv_ada_content);
TextView tvExpand = (TextView) holder.getView(cn.wildfire.chat.kit.R.id.tv_ada_expand);
2. 判断内容是否为空
- 如果内容为空,隐藏内容和展开按钮
- 如果内容不为空,继续处理
3. 重置状态
- 设置tvContent为无限制行数(Integer.MAX_VALUE)
- 清除省略号设置
- 隐藏展开按钮
- 清除点击事件
4. 设置文本内容
tvContent.setText(content);
5. 使用ViewTreeObserver监听布局完成
在布局完成后测量文本行数:
tvContent.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
tvContent.getViewTreeObserver().removeOnPreDrawListener(this);
// 获取实际行数
int lineCount = tvContent.getLineCount();
if (lineCount > 4) {
// 超过4行,显示"全文"按钮
tvContent.setMaxLines(4);
tvContent.setEllipsize(android.text.TextUtils.TruncateAt.END);
tvExpand.setVisibility(View.VISIBLE);
tvExpand.setText("全文");
tvExpand.setTag(false); // false表示收起状态
// 设置点击事件
tvExpand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Boolean isExpanded = (Boolean) tvExpand.getTag();
if (isExpanded == null || !isExpanded) {
// 展开:显示全部内容
tvContent.setMaxLines(Integer.MAX_VALUE);
tvContent.setEllipsize(null);
tvExpand.setText("收起");
tvExpand.setTag(true);
} else {
// 收起:只显示4行
tvContent.setMaxLines(4);
tvContent.setEllipsize(android.text.TextUtils.TruncateAt.END);
tvExpand.setText("全文");
tvExpand.setTag(false);
}
}
});
} else {
// 不超过4行,隐藏展开按钮
tvExpand.setVisibility(View.GONE);
}
return true;
}
});
技术要点
--------
1. ViewTreeObserver的使用
- 使用OnPreDrawListener确保在布局绘制前完成测量
- 测量完成后立即移除监听器,避免重复执行
- 这样可以准确获取TextView的实际行数
2. 状态管理
- 使用View的setTag/getTag方法保存展开/收起状态
- false表示收起状态,true表示展开状态
3. TextView属性控制
- maxLines:控制最大行数
* 4:收起状态,只显示4行
* Integer.MAX_VALUE:展开状态,显示全部内容
- ellipsize:控制省略方式
* TruncateAt.END:在末尾显示省略号
* null:不显示省略号
4. 性能优化
- 只在文本超过4行时显示按钮
- 使用ViewTreeObserver避免重复测量
- 及时移除监听器,避免内存泄漏
功能特点
--------
1. 自动检测
- 自动检测文本是否超过4行
- 超过4行时自动显示"全文"按钮
2. 交互体验
- 点击"全文"展开显示全部内容
- 点击"收起"收起为4行
- 按钮文字动态切换
3. 视觉样式
- 按钮颜色:#ff576b95(蓝色,类似微信风格)
- 按钮位置:内容下方,左对齐
- 按钮大小:14sp,与内容文字一致
4. 边界处理
- 内容为空时,隐藏内容和按钮
- 内容不超过4行时,不显示按钮
- 每次bindView时重置状态,避免状态混乱
使用场景
--------
- 朋友圈列表中的文本内容展示
- 当用户发布的长文本超过4行时,提供展开/收起功能
- 提升用户体验,避免列表项过高影响浏览
注意事项
--------
1. 该功能仅在DiscoveryFragment的朋友圈列表中使用
2. 文本行数判断基于TextView的实际渲染结果
3. 在RecyclerView中,每次bindView都会重新测量和设置状态
4. 展开/收起状态不会持久化,滚动后会重新计算
测试建议
--------
1. 测试短文本(少于4行):不应显示展开按钮
2. 测试长文本(超过4行):应显示"全文"按钮
3. 测试点击"全文":应展开显示全部内容,按钮变为"收起"
4. 测试点击"收起":应收起为4行,按钮变为"全文"
5. 测试空内容:内容和按钮都应隐藏
6. 测试列表滚动:滚动后重新进入视野的项应正确显示状态
版本信息
--------
- 实现日期:2025年
- 修改文件:
* uikit/src/main/res/layout/adapter_pengyouquan_item.xml
* app/src/main/java/com/xunpaisoft/social/im/main/DiscoveryFragment.java