RecyclerView realizes shrinking grouped floating list

       Today, I will share with you a function of using RecyclerView to shrink the grouped floating list. If you just want to realize the function of grouping and shrinking, ExpandListView can do it. This time, we not only need to realize the function of expanding and shrinking, but also realize the group suspension. At the same time, the items that support the suspension are also clickable.

1. Effect diagram


RecyclerView stretch and shrink group suspension

Second, the realization process

       What we want to achieve:
- Each group is expandable and contractible (ExpandListView effect).
- During the sliding process, the parent title of each group should always be fixed at the top (group suspension function).
- Support click function when the parent title of each group is hovering at the top.

       For the group suspension function, you can refer to the previous article RecyclerView group suspension list . It also adds a click function when the group is suspended.

       To achieve the function of stretching and shrinking, first we have to find a way to encapsulate each grouped Entity. Each group contains three parts of information: the title Entity, the list of sub-items Entity, and the current group status (expanded or collapsed).

/**
 * 每个分组对应的entity
 *
 * @param <G> 标题栏entity
 * @param <S> 子项entity
 */
public class ExpandGroupItemEntity<G, S> {

    /**
     * 分组对应的标题栏
     */
    private G       mParent;
    /**
     * 分组里面的子项
     */
    private List<S> mChildList;
    /**
     * 分组展开还是收起
     */
    private boolean mExpand;

    public G getParent() {
        return mParent;
    }

    public void setParent(G parent) {
        mParent = parent;
    }

    public List<S> getChildList() {
        return mChildList;
    }

    public void setChildList(List<S> childList) {
        mChildList = childList;
    }

    public boolean isExpand() {
        return mExpand;
    }

    public void setExpand(boolean expand) {
        mExpand = expand;
    }
}

In order to make it easier for everyone to adapt to no data, generics are used here.

       After the Group Entity is encapsulated. It is the encapsulation of the Adapter. There are two item types in the Adapter: the parent item type of each group, the child item type of the group, and then control which group the item at each position in the adapter belongs to, which corresponds to the parent item or child item of the group. After solving these problems, the functions we need to implement are all out. The Adapter encapsulation code is as follows:

public abstract class RecyclerExpandBaseAdapter<G, C, VH extends RecyclerView.ViewHolder> extends PinnedHeaderAdapter<VH> {

    protected static final int VIEW_TYPE_ITEM_TIME    = 0;
    protected static final int VIEW_TYPE_ITEM_CONTENT = 1;

    protected List<ExpandGroupItemEntity<G, C>>   mDataList;
    protected SparseArray<ExpandGroupIndexEntity> mIndexMap;

    public RecyclerExpandBaseAdapter() {
        this(null);
    }

    public RecyclerExpandBaseAdapter(List<ExpandGroupItemEntity<G, C>> dataList) {
        mDataList = dataList;
        mIndexMap = new SparseArray<>();
    }

    public void setData(List<ExpandGroupItemEntity<G, C>> dataList) {
        mDataList = dataList;
        mIndexMap.clear();
        notifyDataSetChanged();
    }

    public List<ExpandGroupItemEntity<G, C>> getData() {
        return mDataList;
    }

    @Override
    public boolean isPinnedPosition(int position) {
        return getItemViewType(position) == VIEW_TYPE_ITEM_TIME;
    }

    @Override
    public int getItemViewType(int position) {
        int count = 0;
        for (ExpandGroupItemEntity<G, C> item : mDataList) {
            count = count + 1;
            if (position == count - 1) {
                return VIEW_TYPE_ITEM_TIME;
            }
            if (item.getChildList() != null && item.isExpand()) {
                count = count + item.getChildList().size();
            }
            if (position < count) {
                return VIEW_TYPE_ITEM_CONTENT;
            }
        }
        throw new IllegalArgumentException("getItemViewType exception");
    }

    @Override
    public int getItemCount() {
        if (mDataList == null || mDataList.isEmpty()) {
            return 0;
        }
        int count = 0;
        for (int group = 0; group < mDataList.size(); group++) {
            ExpandGroupItemEntity<G, C> item = mDataList.get(group);
            //标题
            count = count + 1;

            mIndexMap.put(count - 1, new ExpandGroupIndexEntity(group, -1, item.getChildList() == null ? 0 : item.getChildList().size()));
            int childStartPosition = count;
            if (item.getChildList() != null && item.isExpand()) {
                //sub
                count = count + item.getChildList().size();
            }
            int childEndPosition = count;
            for (int loop = childStartPosition; loop < childEndPosition; loop++) {
                mIndexMap.put(loop, new ExpandGroupIndexEntity(group, loop - childStartPosition,
                                                               item.getChildList() == null ? 0 : item.getChildList().size()));
            }
        }
        return count;
    }

}

       Regarding the specific details, the introduction in the article is relatively simple. For more specific details, you can refer to the download address of the code example (note that it is the module corresponding to recyclerexpand)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324684550&siteId=291194637