219 lines
7.5 KiB
Plaintext
219 lines
7.5 KiB
Plaintext
全文和收起功能实现文档
|
||
=====================================
|
||
|
||
功能描述
|
||
--------
|
||
在朋友圈列表(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
|
||
android:id="@+id/tv_ada_content"
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:text="你说你孤独,像很久以前火星照耀十三州府像很久以前火星照耀十三州府像很久以前火星照耀十三州府"
|
||
android:textColor="#ff1a193e"
|
||
android:textSize="@dimen/dimen_14sp"
|
||
android:layout_marginTop="@dimen/dimen_16dp"
|
||
/>
|
||
|
||
修改后:
|
||
<LinearLayout
|
||
android:layout_width="match_parent"
|
||
android:layout_height="wrap_content"
|
||
android:orientation="vertical"
|
||
android:layout_marginTop="@dimen/dimen_16dp">
|
||
|
||
<TextView
|
||
android:id="@+id/tv_ada_content"
|
||
android:layout_width="match_parent"
|
||
android:layout_height="wrap_content"
|
||
android:text="你说你孤独,像很久以前火星照耀十三州府像很久以前火星照耀十三州府像很久以前火星照耀十三州府"
|
||
android:textColor="#ff1a193e"
|
||
android:textSize="@dimen/dimen_14sp"
|
||
android:maxLines="4"
|
||
android:ellipsize="end"
|
||
/>
|
||
|
||
<TextView
|
||
android:id="@+id/tv_ada_expand"
|
||
android:layout_width="wrap_content"
|
||
android:layout_height="wrap_content"
|
||
android:text="全文"
|
||
android:textColor="#ff576b95"
|
||
android:textSize="@dimen/dimen_14sp"
|
||
android:layout_marginTop="@dimen/dimen_4dp"
|
||
android:visibility="gone"
|
||
android:clickable="true"
|
||
android:focusable="true"
|
||
/>
|
||
</LinearLayout>
|
||
|
||
说明:
|
||
- 将原来的单个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
|
||
|