RecyclerView单层RecyclerView实现点击展开、折叠效果

2022年8月5日11:15:13

RecyclerView单层RecyclerView实现点击展开、折叠效果

最近有RecyclerView点击展开、折叠item的需求,其中一种写法是利用两个RecyclerView实现,但这样效率不高。因此采用单层RecyclerView来实现此需求。

1 定义两个布局item的结构,Adapter的数据源为两种item组装成的集合

1.1 子item:ChildBookItem

简单起见,只展示一个bookName

private String bookName;

1.2 父item:CategoryItem

privateint index;privateboolean isShow;// 展开状态private String categoryName;private List<ChildBookItem> childBookItems;// 子item列表

index表示在item集合中此CategoryItem的位置(不算ChildBookItem的数量);
List childBookItems 是此Category在展开状态下所包含的子item集合,只用于记录对应关系,并不参与绘制UI。

2 组装数据

2.1 获取数据源

private List<BookShelf>initData(){

        BookShelf bookShelf1=newBookShelf();
        bookShelf1.setName("科幻类");
        String[] books1=newString[]{"三体","流浪地球","降临"};
        bookShelf1.setBooks(Arrays.asList(books1));
        mDatas.add(bookShelf1);

        BookShelf bookShelf2=newBookShelf();
        bookShelf2.setName("政治类");
        String[] books2=newString[]{"美国陷阱","从赫鲁晓夫到普京","为什么是以色列","南京大屠杀"};
        bookShelf2.setBooks(Arrays.asList(books2));
        mDatas.add(bookShelf2);

        BookShelf bookShelf3=newBookShelf();
        bookShelf3.setName("文学类");
        String[] books3=newString[]{"我们仨","小姨多鹤","我与地坛","黄金时代","雪国"};
        bookShelf3.setBooks(Arrays.asList(books3));
        mDatas.add(bookShelf3);return mDatas;}

2.2 初始化组装item

由于初始不展示子item,所以不需要设置ChildBookItems的内容。此时定义的Adapter绑定的集合类型为Object,既包含CategoryItem,也包括ChildBookItem,所以不指定具体类型。

private List<Object> mList=newArrayList<>();// item组装数据private List<CategoryItem>initItem(){
        List<BookShelf> bookShelves=initData();
        List<CategoryItem> items=newArrayList<>();for(int i=0; i< bookShelves.size(); i++){
            BookShelf bookShelf= bookShelves.get(i);

            CategoryItem categoryItem=newCategoryItem();
            categoryItem.setIndex(i);
            categoryItem.setShow(false);
            categoryItem.setCategoryName(bookShelf.getName());
            categoryItem.setChildBookItems(newArrayList<ChildBookItem>());
            items.add(categoryItem);}return items;}

RecyclerView单层RecyclerView实现点击展开、折叠效果
此时的items包含了三条数据,均为父item类型

2.3 根据item的不同,在Adapter中调用不同的ViewHolder

BookViewHolder与CategoryViewHolder均为继承BaseViewHolder的ViewHolder,可在两个文件中分别进行item相关UI展示。
下边为Adapter部分关键代码:

public BaseViewHolderonCreateViewHolder(@NonNull ViewGroup viewGroup,int i){switch(i){case TYPE_CATEGORY:returnnewCategoryViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_category_item, viewGroup,false),this);case TYPE_BOOK:returnnewBookViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_item_book, viewGroup,false));default:returnnewBaseViewHolder(newLinearLayout(viewGroup.getContext())){@OverridepublicvoidbindView(List list, Object obj){}};}}@OverridepublicintgetItemViewType(int position){
        Object obj= mDatas.get(position);if(objinstanceofCategoryItem){return TYPE_CATEGORY;}elseif(objinstanceofChildBookItem){return TYPE_BOOK;}return-1;}@OverridepublicvoidonBindViewHolder(@NonNull BaseViewHolder baseViewHolder,int i){
        baseViewHolder.bindView(mDatas, mDatas.get(i));}

3 点击操作

3.1 展开子item

mList.addAll(mSelectedPosition + 1, childBookItems):将ChildBookItem集合加入到适配器绑定数据集合中,位置在刚刚点击的父item后一位;
mSelectedPosition:为刚刚点击的父item的position;
categoryItem.setChildBookItems(childBookItems):确定父item与子item集合的对应关系,方便后边折叠item时候直接从mList中删除此集合。

// 展开子itemprivatevoidaddChildItems(int index){
        List<String> bookList= mDatas.get(index).getBooks();
        List<ChildBookItem> childBookItems=newArrayList<>();for(int i=0; i< bookList.size(); i++){
            ChildBookItem item=newChildBookItem();
            item.setBookName(bookList.get(i));
            childBookItems.add(item);}
        mList.addAll(mSelectedPosition+1, childBookItems);// 添加子item
        CategoryItem categoryItem=(CategoryItem) mList.get(mSelectedPosition);
        categoryItem.setChildBookItems(childBookItems);
        mAdapter.notifyDataSetChanged();}

若此时点击最后一个父item,可看到mList中前三条数据为CategoryItem类型;后五条数据为ChildBookItem类型,并与第三条CategoryItem的子item列表内容相同。
RecyclerView单层RecyclerView实现点击展开、折叠效果

3.2 折叠子item

mList.removeAll(item.getChildBookItems()): 由于之前展开item的时候已经设置好了CategoryItem与ChildBookItem之间的对应关系,所以可通过此行代码直接从mList中删除子item。

privatevoidremoveChildItems(){
        CategoryItem item=(CategoryItem)mList.get(mSelectedPosition);
        mList.removeAll(item.getChildBookItems());
        item.setChildBookItems(newArrayList<ChildBookItem>());
        mAdapter.notifyDataSetChanged();}

4 demo下载

可在这里下载单层RecyclerView实现点击展开、折叠效果的demo

  • 作者:樱花雨2377
  • 原文链接:https://blog.csdn.net/qq_31573123/article/details/101290683
    更新时间:2022年8月5日11:15:13 ,共 3856 字。