当前位置:网站首页>Use RecyclerView to implement three-level collapsed list
Use RecyclerView to implement three-level collapsed list
2022-08-09 13:17:00 【Xie Dong_】
开题:RecyclerViewIt can be described as a control for developing Android,Needless to say, use and power,If you, as a judge, don't know much about itRecyclerView的具体使用,It is recommended to hurry up to supplement the knowledge.What I am sharing with you today isRecyclerViewOn the basis of expanding the specific example of the three-level folding list,I will still do the same as the previous blog post,Combined with my example code, I will write and analyze it with you.
实现分析:
1.First of all, the three-level list is still one after allRecyclerView,It's just that you need to add sub-layoutsitem下,插入一个Item,重新计算了,各个Item之间的位置关系,以及position的值.
2.The three-level list needs to be based on the folding relationship between the three levels,Define a different parent、子ViewHolder,然后在Adapter根据typeDistinguish what currently needs to be insertedItemIt belongs to the level of layout(The three-level parent-child layout relationship).
3.需要在父、子ViewHolder中的bindVieware bound to different onesview视图,And do view filling and click event handling.
4.需要在Adapter中绑定Item点击回调接口,Used to determine the current level(父子孙)View is requiredadd还是remove子View,and recalculate the currentItem的currentPostion.
5.Finally fill in the data toAdapter,然后把Adapter绑定到RecyclerView上.
The general idea is this,I've been thinking about it time and time again with you all,So that the judges have a way in their hearts,接下来,Combined with my example code,Look and talk.
首先是ExpandSectionAdapter.java:Almost the core is mainly the processing of this class,里面实现了,对ItemThe listener of the click callback interface,判断childView的显示隐藏,以及remove跟addview方法的实现,代码比较详细,I will not explain the method in it alone,代码贴上.
/**
* desc :Collapsible and expandableAdapter
* author:xiedong
* data:2018/3/5
*/
public class ExpandSectionAdapter extends RecyclerView.Adapter<BaseViewHolder> {
private Context context;
private List<SelectSectionParentEntity> dataBeanList;
private LayoutInflater mInflater;
private OnScrollListener mOnScrollListener;
public ExpandSectionAdapter(Context context, List<SelectSectionParentEntity> dataBeanList) {
this.context = context;
this.dataBeanList = dataBeanList;
this.mInflater = LayoutInflater.from(context);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
switch (viewType){
case SelectSectionParentEntity.PARENT_ITEM:
view = mInflater.inflate(R.layout.layout_section_list_parent, parent, false);
return new ParentViewHolder(context, view);
case SelectSectionParentEntity.CHILD_ITEM:
view = mInflater.inflate(R.layout.layout_section_list_child, parent, false);
return new ChildViewHolder(context, view);
default:
view = mInflater.inflate(R.layout.layout_section_list_parent, parent, false);
return new ParentViewHolder(context, view);
}
}
/**
* Bind according to different typesView
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
switch (getItemViewType(position)){
case SelectSectionParentEntity.PARENT_ITEM:
ParentViewHolder parentViewHolder = (ParentViewHolder) holder;
parentViewHolder.bindView(dataBeanList.get(position), position, itemClickListener);
break;
case SelectSectionParentEntity.CHILD_ITEM:
ChildViewHolder childViewHolder = (ChildViewHolder) holder;
childViewHolder.bindView(dataBeanList.get(position), position);
break;
}
}
@Override
public int getItemCount() {
return dataBeanList.size();
}
@Override
public int getItemViewType(int position) {
return dataBeanList.get(position).getType();
}
private ExpandListClickListener itemClickListener = new ExpandListClickListener() {
@Override
public void onExpandChildren(SelectSectionParentEntity bean) {
int position = getCurrentPosition(bean.getID());//Determines what is currently clickeditem位置
SelectSectionParentEntity children = getChildDataBean(bean);//Get the child layout data object to display,注意区分onHideChildren方法中的getChildBean().
if (children == null) {
return;
}
add(children, position + 1);//在当前的item下方插入
System.out.println(position+"------------");
if (position == dataBeanList.size() - 2 && mOnScrollListener != null) { //如果点击的item为最后一个
mOnScrollListener.scrollTo(position + 1);//向下滚动,Make the sub-layout fully displayable
}
}
@Override
public void onHideChildren(SelectSectionParentEntity bean) {
int position = getCurrentPosition(bean.getID());//Determines what is currently clickeditem位置
SelectSectionParentEntity children = bean.getChildBean();//Get the child layout object
if (children == null) {
return;
}
remove(position + 1);//删除
if (mOnScrollListener != null) {
mOnScrollListener.scrollTo(position);
}
}
};
/**
* Insert a piece of data below the parent layout
* @param bean
* @param position
*/
public void add(SelectSectionParentEntity bean, int position) {
dataBeanList.add(position, bean);
notifyItemInserted(position);
}
/**
*Remove child layout data
* @param position
*/
protected void remove(int position) {
dataBeanList.remove(position);
notifyItemRemoved(position);
}
/**
* Determines what is currently clickeditemlocation and return
* @param uuid
* @return
*/
protected int getCurrentPosition(String uuid) {
for (int i = 0; i < dataBeanList.size(); i++) {
if (uuid.equalsIgnoreCase(dataBeanList.get(i).getID())) {
return i;
}
}
return -1;
}
/**
* Encapsulates the child layout data object and returns it
* 注意,Just repackage one hereDataBean对象,为了标注TypeLayout data for the child,进而展开,展示数据
* 要和onHideChildren方法里的getChildBean()区分开来
* @param bean
* @return
*/
private SelectSectionParentEntity getChildDataBean(SelectSectionParentEntity bean){
SelectSectionParentEntity child = new SelectSectionParentEntity();
child.setType(1);
child.setParentLeftTxt(bean.getParentLeftTxt());
child.setParentRightTxt(bean.getParentRightTxt());
child.setChildLeftTxt(bean.getChildLeftTxt());
child.setChildRightTxt(bean.getChildRightTxt());
return child;
}
/**
* Scroll listener interface
*/
public interface OnScrollListener{
void scrollTo(int pos);
}
public void setOnScrollListener(OnScrollListener onScrollListener){
this.mOnScrollListener = onScrollListener;
}
}
监听子ViewDisplay the click callback interface of the hidden state:
/**
* desc :Collapsible and expandableRecycleView回调接口
* author:xiedong
* data:2018/3/5
*/
public interface ExpandListClickListener {
/**
* Expand subItem
*
* @param entity
*/
void onExpandChildren(SelectSectionParentEntity entity);
/**
* 隐藏子Item
*
* @param entity
*/
void onHideChildren(SelectSectionParentEntity entity);
}
接下来是父、子ViewHodler,Because father and son need itbind不同的视图 ,All to the Father、子Viewholder进行分开处理,Both inheritBaseViewHolder.
父ViewHodler.java:
/**
* desc :Collapsible and expandableRecycleView Parent holder
* author:xiedong
* data:2018/3/5
*/
public class ParentViewHolder extends BaseViewHolder {
private Context mContext;
private View view;
private RelativeLayout containerLayout;
private TextView parentLeftView;
private TextView parentRightView;
private ImageView expand;
private View parentDashedView;
public ParentViewHolder(Context context, View itemView) {
super(itemView);
this.mContext = context;
this.view = itemView;
}
public void bindView(final SelectSectionParentEntity dataBean, final int pos, final ExpandListClickListener listener) {
containerLayout = (RelativeLayout) view.findViewById(R.id.container);
parentLeftView = (TextView) view.findViewById(R.id.tv_section_type_parent);
parentLeftView.setText(dataBean.getParentLeftTxt());
//父布局OnClick监听
containerLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
if (dataBean.isExpand()) {
listener.onHideChildren(dataBean);
// parentDashedView.setVisibility(View.VISIBLE);
dataBean.setExpand(false);
} else {
listener.onExpandChildren(dataBean);
// parentDashedView.setVisibility(View.INVISIBLE);
dataBean.setExpand(true);
}
}
}
});
}
}
子ViewHodler.java:
/**
* desc :Collapsible and expandableRecycleView child holder
* author:xiedong
* data:2018/3/5
*/
public class ChildViewHolder extends BaseViewHolder {
private RelativeLayout containerLayout;
private Context mContext;
private View view;
private TextView childLeftText;
private TextView childRightText;
public ChildViewHolder(Context context, View itemView) {
super(itemView);
this.mContext = context;
this.view = itemView;
}
public void bindView(final SelectSectionParentEntity dataBean, final int pos) {
containerLayout = (RelativeLayout) view.findViewById(R.id.rl_child_container);
final LinearLayout grandChildContainer = (LinearLayout)view.findViewById(R.id.ll_gradnchild_container);
childLeftText = (TextView) view.findViewById(R.id.tv_section_type_child);
childLeftText.setText(dataBean.getChildLeftTxt());
containerLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
grandChildContainer.removeAllViews();
System.out.println("dfsa" + "---------------------");
GrandChildrenSectionView grandChildrenSectionView = new GrandChildrenSectionView(mContext);
grandChildContainer.addView(grandChildrenSectionView);
}
});
}
}
对viewHolder的处理比较简单,bingView之后,对viewDo filling and click event processing,The next two inheritBaseViewHodlerIt was packaged by me referring to the great god on the InternetBaseViewHodler,Also posted to share with everyone.
BaseViewHodler.java
public class BaseViewHolder extends ViewHolder {
private final SparseArray<View> views;
private final LinkedHashSet<Integer> childClickViewIds;
private final LinkedHashSet<Integer> itemChildLongClickViewIds;
public View convertView;
Object associatedObject;
public BaseViewHolder(View view) {
super(view);
AutoUtils.auto(view);
this.views = new SparseArray();
this.childClickViewIds = new LinkedHashSet();
this.itemChildLongClickViewIds = new LinkedHashSet();
this.convertView = view;
}
public HashSet<Integer> getItemChildLongClickViewIds() {
return this.itemChildLongClickViewIds;
}
public HashSet<Integer> getChildClickViewIds() {
return this.childClickViewIds;
}
public View getConvertView() {
return this.convertView;
}
public BaseViewHolder setText(int viewId, CharSequence value) {
TextView view = (TextView)this.getView(viewId);
view.setText(value);
return this;
}
public BaseViewHolder setText(int viewId, @StringRes int strId) {
TextView view = (TextView)this.getView(viewId);
view.setText(strId);
return this;
}
public BaseViewHolder setImageResource(int viewId, @DrawableRes int imageResId) {
ImageView view = (ImageView)this.getView(viewId);
view.setImageResource(imageResId);
return this;
}
public BaseViewHolder setBackgroundColor(int viewId, int color) {
View view = this.getView(viewId);
view.setBackgroundColor(color);
return this;
}
public BaseViewHolder setBackgroundRes(int viewId, @DrawableRes int backgroundRes) {
View view = this.getView(viewId);
view.setBackgroundResource(backgroundRes);
return this;
}
public BaseViewHolder setTextColor(int viewId, int textColor) {
TextView view = (TextView)this.getView(viewId);
view.setTextColor(textColor);
return this;
}
public BaseViewHolder setImageDrawable(int viewId, Drawable drawable) {
ImageView view = (ImageView)this.getView(viewId);
view.setImageDrawable(drawable);
return this;
}
public BaseViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
ImageView view = (ImageView)this.getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
public BaseViewHolder setAlpha(int viewId, float value) {
if(VERSION.SDK_INT >= 11) {
this.getView(viewId).setAlpha(value);
} else {
AlphaAnimation alpha = new AlphaAnimation(value, value);
alpha.setDuration(0L);
alpha.setFillAfter(true);
this.getView(viewId).startAnimation(alpha);
}
return this;
}
public BaseViewHolder setVisible(int viewId, boolean visible) {
View view = this.getView(viewId);
view.setVisibility(visible?0:8);
return this;
}
public BaseViewHolder linkify(int viewId) {
TextView view = (TextView)this.getView(viewId);
Linkify.addLinks(view, 15);
return this;
}
public BaseViewHolder setTypeface(int viewId, Typeface typeface) {
TextView view = (TextView)this.getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | 128);
return this;
}
public BaseViewHolder setTypeface(Typeface typeface, int... viewIds) {
int[] var3 = viewIds;
int var4 = viewIds.length;
for(int var5 = 0; var5 < var4; ++var5) {
int viewId = var3[var5];
TextView view = (TextView)this.getView(viewId);
view.setTypeface(typeface);
view.setPaintFlags(view.getPaintFlags() | 128);
}
return this;
}
public BaseViewHolder setProgress(int viewId, int progress) {
ProgressBar view = (ProgressBar)this.getView(viewId);
view.setProgress(progress);
return this;
}
public BaseViewHolder setProgress(int viewId, int progress, int max) {
ProgressBar view = (ProgressBar)this.getView(viewId);
view.setMax(max);
view.setProgress(progress);
return this;
}
public BaseViewHolder setMax(int viewId, int max) {
ProgressBar view = (ProgressBar)this.getView(viewId);
view.setMax(max);
return this;
}
public BaseViewHolder setRating(int viewId, float rating) {
RatingBar view = (RatingBar)this.getView(viewId);
view.setRating(rating);
return this;
}
public BaseViewHolder setRating(int viewId, float rating, int max) {
RatingBar view = (RatingBar)this.getView(viewId);
view.setMax(max);
view.setRating(rating);
return this;
}
/** @deprecated */
@Deprecated
public BaseViewHolder setOnClickListener(int viewId, OnClickListener listener) {
View view = this.getView(viewId);
view.setOnClickListener(listener);
return this;
}
public BaseViewHolder addOnClickListener(int viewId) {
this.childClickViewIds.add(Integer.valueOf(viewId));
return this;
}
public BaseViewHolder addOnLongClickListener(int viewId) {
this.itemChildLongClickViewIds.add(Integer.valueOf(viewId));
return this;
}
public BaseViewHolder setOnTouchListener(int viewId, OnTouchListener listener) {
View view = this.getView(viewId);
view.setOnTouchListener(listener);
return this;
}
public BaseViewHolder setOnLongClickListener(int viewId, OnLongClickListener listener) {
View view = this.getView(viewId);
view.setOnLongClickListener(listener);
return this;
}
public BaseViewHolder setOnItemClickListener(int viewId, OnItemClickListener listener) {
AdapterView view = (AdapterView)this.getView(viewId);
view.setOnItemClickListener(listener);
return this;
}
public BaseViewHolder setOnItemLongClickListener(int viewId, OnItemLongClickListener listener) {
AdapterView view = (AdapterView)this.getView(viewId);
view.setOnItemLongClickListener(listener);
return this;
}
public BaseViewHolder setOnItemSelectedClickListener(int viewId, OnItemSelectedListener listener) {
AdapterView view = (AdapterView)this.getView(viewId);
view.setOnItemSelectedListener(listener);
return this;
}
public BaseViewHolder setOnCheckedChangeListener(int viewId, OnCheckedChangeListener listener) {
CompoundButton view = (CompoundButton)this.getView(viewId);
view.setOnCheckedChangeListener(listener);
return this;
}
public BaseViewHolder setTag(int viewId, Object tag) {
View view = this.getView(viewId);
view.setTag(tag);
return this;
}
public BaseViewHolder setTag(int viewId, int key, Object tag) {
View view = this.getView(viewId);
view.setTag(key, tag);
return this;
}
public BaseViewHolder setChecked(int viewId, boolean checked) {
View view = this.getView(viewId);
if(view instanceof CompoundButton) {
((CompoundButton)view).setChecked(checked);
} else if(view instanceof CheckedTextView) {
((CheckedTextView)view).setChecked(checked);
}
return this;
}
public BaseViewHolder setAdapter(int viewId, Adapter adapter) {
AdapterView view = (AdapterView)this.getView(viewId);
view.setAdapter(adapter);
return this;
}
public <T extends View> T getView(int viewId) {
View view = (View)this.views.get(viewId);
if(view == null) {
view = this.convertView.findViewById(viewId);
this.views.put(viewId, view);
}
return view;
}
public Object getAssociatedObject() {
return this.associatedObject;
}
public void setAssociatedObject(Object associatedObject) {
this.associatedObject = associatedObject;
}
}
At this point, basically the important work has been done,剩下的就是给Adapter填充数据.We simulate two entity classes,respectively for the parent、子viewThe entity that populates the data,i omitset、get方法,Only the attributes are posted for your reference.ParentEntity类:
public class SelectSectionParentEntity {
public static final int PARENT_ITEM = 0;//父布局
public static final int CHILD_ITEM = 1;//子布局
private int type;// 显示类型
private boolean isExpand;// 是否展开
private SelectSectionParentEntity childBean;
private String ID;
private String parentLeftTxt;
private String parentRightTxt;
private String childLeftTxt;
private String childRightTxt;
}
ChildEntity类:
public class SelectSectionChildEntity {
public static final int PARENT_ITEM = 0;//父布局
public static final int CHILD_ITEM = 1;//子布局
private int type;// 显示类型
private boolean isExpand;// 是否展开
private SelectSectionChildEntity childBean;
private String ID;
private String parentLeftTxt;
private String parentRightTxt;
private String childLeftTxt;
private String childRightTxt;
}
The last thing is to simulate filling the data:
/**
* 模拟数据
*/
private void initData() {
dataBeanList = new ArrayList<>();
SelectSectionChildEntity childEntity = new SelectSectionChildEntity();
List<SelectSectionChildEntity> childEntityList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
sectionEntity = new SelectSectionParentEntity();
sectionEntity.setID(i + "");
sectionEntity.setType(0);
sectionEntity.setParentLeftTxt("父--" + i);
sectionEntity.setParentRightTxt("父内容--" + i);
sectionEntity.setChildLeftTxt("子--" + i);
sectionEntity.setChildRightTxt("子内容--" + i);
sectionEntity.setChildBean(sectionEntity);
//添加子布局
childEntity.setID(i + "");
childEntity.setType(0);
childEntity.setParentLeftTxt("父--" + i);
childEntity.setParentRightTxt("父内容--" + i);
childEntity.setChildLeftTxt("子--" + i);
childEntity.setChildRightTxt("子内容--" + i);
childEntity.setChildBean(childEntity);
childEntityList.add(childEntity);
dataBeanList.add(sectionEntity);
}
setData();
}
private void setData() {
trvSection.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new ExpandSectionAdapter(this, dataBeanList);
trvSection.setAdapter(mAdapter);
//滚动监听
mAdapter.setOnScrollListener(new ExpandSectionAdapter.OnScrollListener() {
@Override
public void scrollTo(int pos) {
trvSection.scrollToPosition(pos);
}
});
}
The general realization of the idea is as above,I just built a simple shell,The specific use also requires the officials to do secondary encapsulation on this basis according to business needs,Share as above,如有不妥之处,I also ask the officials to criticize and correct the righteousness.
边栏推荐
- 二叉树的序列化和反序列化
- Programmer's Exclusive Romance - Use 3D Engine to Realize Fireworks in 5 Minutes
- 国产抗新冠口服药每瓶不超300元/ 我国IPv6网络全面建成/ 谷歌入局折叠屏手机...今日更多新鲜事在此...
- Here comes the question: Can I successfully apply for 8G memory on a machine with 4GB physical memory?
- 基于STM32+铂电阻设计的测温仪
- API调用,API传参,面向对接开发,你真的会写接口文档吗?
- 箭头函数和普通函数的常见区别
- 微信一面:一致性哈希是什么,使用场景,解决了什么问题?
- 非科班AI小哥火了:他没有ML学位,却拿到DeepMind的offer
- Too much volume... Tencent was asked on the side that the memory was full, what would happen?
猜你喜欢
HAproxy: load balancing
Too much volume... Tencent was asked on the side that the memory was full, what would happen?
MySQL 原理与优化,Group By 优化 技巧
#物联网征文#小熊派设备开发实战
ABAP interview questions: how to use the System CALL interface of the ABAP programming language, direct execution ABAP server operating System's shell command?
【Untitled】
LeetCode #101. Symmetric Binary Tree
告别手摇织布机的AI时代
用场景定义硬件,英码科技破解“边缘计算”密码
你没见过的《老友记》镜头,AI给补出来了|ECCV 2022
随机推荐
Apexsqlrecover无法连接数据库
【HCIP持续更新】IS-IS协议原理与配置
900页数学论文证明旋转的黑洞不会爆炸,丘成桐:30多年来广义相对论首次重大突破...
曼城推出可检测情绪的智能围巾,把球迷给整迷惑了
Adalvo收购其首个品牌产品Onsolis
#Internet of Things essay#Xiaoxiong pie equipment development actual combat
Intra-group reverse order adjustment of K nodes
读写分离后,性能居然提升100%了呀
数字化转型之支撑保障单元
Report: The number of students who want to learn AI has increased by 200%, and there are not enough teachers
Intranet penetration tool ngrok usage tutorial
MySQL5.6到8.0的账号迁移
超越CLIP的多模态模型,只需不到1%的训练数据!南加大最新研究来了
Too much volume... Tencent was asked on the side that the memory was full, what would happen?
随机快排时间复杂度是N平方?
史上最猛“员工”,疯狂吐槽亿万富翁老板小扎:那么有钱,还总穿着同样的衣服!...
AI basketball referee, walking is special, ask harden care don't care
2022牛客多校(六)M. Z-Game on grid
自定义VIEW实现应用内消息提醒上下轮播
放下手机吧:实验表明花20分钟思考和上网冲浪同样快乐