点击RecycleView条目展开收缩
原文链接:https://blog.youkuaiyun.com/weixin_34211761/article/details/87305545
1.可展开收起的TextView
public class ExpandTextView extends AppCompatTextView{
/**
* true 展开 false 收起
*/
boolean mExpanded;
/**
* 返回状态
*/
Callback mCallback;
/**
* 原文字内容
*/
String mText;
/**
* 最多展示的行数
*/
final int maxLineCount = 3;
/**
* 省略文字
*/
final String ellipsizeText = "... 展开";
final String expandsizeText = "收缩";
public ExpandTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//文字计算辅助工具
StaticLayout s1 = new StaticLayout(mText,getPaint(),getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
Layout.Alignment.ALIGN_CENTER,1,0,true);
//计算行数
int lineCount = s1.getLineCount();
if(lineCount > maxLineCount){
if(mExpanded){
String newText = mText+expandsizeText;
SpannableStringBuilder stringBuilder=new SpannableStringBuilder(newText);
stringBuilder.setSpan(new ForegroundColorSpan(Color.parseColor("#FF971B")),newText.length()-expandsizeText.length(),newText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(stringBuilder);
mCallback.onExpand();
}else {
lineCount = maxLineCount;
//省略文字的宽度
float dotWith = getPaint().measureText(ellipsizeText);
//找出第showlinecount行的文字
int start = s1.getLineStart(lineCount -1);
int end = s1.getLineEnd(lineCount -1);
String lineText = mText.substring(start,end);
//将第showlinecount行最后的文字替换成ellipsizeText
int endIndex = 0;
for(int i= lineText.length() -1; i >= 0;i--){
String str = lineText.substring(i,lineText.length());
//找出文字宽度大于ellipsizeText的字符
if(getPaint().measureText(str) >=dotWith){
endIndex = i;
break;
}
}
//新的第showLineCount的文字
String newEndLineText = lineText.substring(0,endIndex) +ellipsizeText;
SpannableString spannableString = new SpannableString(mText.substring(0,start) + newEndLineText);
spannableString.setSpan(new ForegroundColorSpan(Color.parseColor("#FF971B")), mText.substring(0,end).length(),(mText.substring(0,start) + newEndLineText).length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//最终显示的文字
// setText(mText.substring(0,start) + newEndLineText);
setText(spannableString);
mCallback.onCollapse();
}
}else{
setText(mText);
mCallback.onLoss();
}
//重新计算高度
int lineHeight = 0;
for(int i = 0;i < lineCount;i++){
Rect lineBound = new Rect();
s1.getLineBounds(i,lineBound);
lineHeight +=lineBound.height();
}
lineHeight += getPaddingTop() + getPaddingBottom();
setMeasuredDimension(getMeasuredWidth(),lineHeight);
}
/**
* 设置要显示的文字以及状态
* @param text
* @param expanded true:展开,false:收起
* @param callback
*/
public void setText(String text, boolean expanded, Callback callback) {
mText = text;
mExpanded = expanded;
mCallback = callback;
// 设置要显示的文字,这一行必须要,否则 onMeasure 宽度测量不正确
setText(text);
}
/**
* 展开收起状态变化
* @param expanded
*/
public void setChanged(boolean expanded) {
mExpanded = expanded;
requestLayout();
}
/**
* 结果回调
*/
public interface Callback{
/**
* 展开状态
*/
void onExpand();
/**
* 收起状态
*/
void onCollapse();
/**
* 行数小于最小行数,不满足展开或这是收起条件
*/
void onLoss();
}
}
二.引入布局文件
1.在Activity的xml文件中引入RecycleView
<android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recycle_view_item"/>
2.Adapter的item的xml文件
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" app:cardCornerRadius="@dimen/space_14" app:cardElevation="@dimen/space_4" android:layout_margin="@dimen/space_10" android:background="@color/transparent"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#33ff0000" android:padding="@dimen/space_10"> <ImageView android:id="@+id/recycle_iv_icon" android:layout_width="40dp" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:src="@mipmap/ic_launcher"/> <com.hjq.demo.widget.ExpandTextView android:id="@+id/recycle_tv_message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:layout_centerVertical="true" android:layout_toRightOf="@id/recycle_iv_icon" android:layout_toLeftOf="@id/recycle_icon" android:text="让我们成为好友吧?" /> <ImageView android:id="@+id/recycle_icon" android:layout_width="20dp" android:layout_height="20dp" android:layout_centerVertical="true" android:layout_marginLeft="2dp" android:layout_alignParentRight="true" android:src="@mipmap/ic_launcher"/> </RelativeLayout> </android.support.v7.widget.CardView>
三.适配器的引用
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<Data> itemDataList; public MyAdapter(List<Data> dataList) { this.itemDataList = dataList; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { return new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.itemfour, viewGroup, false)); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { final ViewHolder viewH = (ViewHolder) viewHolder; final Data data = itemDataList.get(i); viewH.tv_message.setText(itemDataList.get(i).getProduct(), itemDataList.get(i).isExpanded(), new ExpandTextView.Callback() { @Override public void onExpand() { // 展开状态,比如:显示“收起”按钮 } @Override public void onCollapse() { // 收缩状态,比如:显示“全文”按钮 } @Override public void onLoss() { // 不满足展开的条件,比如:隐藏“全文”按钮 } }); viewH.recycle_icon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 保存当前行的状态 data.setExpanded(!data.isExpanded()); // 切换状态 viewH.tv_message.setChanged(data.isExpanded()); } }); } @Override public int getItemCount() { return itemDataList.size(); } class ViewHolder extends RecyclerView.ViewHolder { ImageView img_icon,recycle_icon; ExpandTextView tv_message; public ViewHolder(@NonNull View itemView) { super(itemView); img_icon = itemView.findViewById(R.id.recycle_iv_icon); recycle_icon = itemView.findViewById(R.id.recycle_icon); tv_message = itemView.findViewById(R.id.recycle_tv_message); } } }
四.创建的bean
public class Data implements Serializable { private String product; private boolean expanded; public String getProduct() { return product; } public void setProduct(String product) { this.product = product; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public Data(String product) { this.product = product; } }
五.MainActivity的使用
RecyclerView view=findViewById(R.id.recycle_view_item); view.setLayoutManager(new LinearLayoutManager(getContext(),LinearLayoutManager.VERTICAL,false)); List<Data> list=new ArrayList<>(); Data data1=new Data("培训课程 -> lambda表达式与集合一起使用,是最常见的场景,可以各种筛选、映射、变换操作符和对集合数据进行各种操作,非常灵活,相信使用过RxJava中的开发者已经体会到这种快感,没错Kotlin在语言层面,无需增加额外库,就给你提供了支持函数式编程API。"); list.add(data1); Data data2=new Data("培训课程 ->我们试想一个场景就是可能会用到多个lambda表达式,但是这些lambda表达式的类型很多相同,我们就很容易把所有相同一大串的Lambda类型重复声明或者你的lambda类型声明太长不利于阅读。实际上不需要,对于Kotlin这门反对一切啰嗦语法的语言来说,它都给你提供一系列的解决办法,让你简化代码的同时又不降低代码的可读性。\n"); list.add(data2); MyAdapter myAdapter = new MyAdapter(list); view.setAdapter(myAdapter);
本文介绍如何在Android应用中使用自定义的ExpandTextView组件,在RecycleView内实现文本内容的展开与收缩效果。通过创建适配器并集成到RecycleView中,能够根据用户点击动态调整文本的显示范围。
503

被折叠的 条评论
为什么被折叠?



