欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

从中间展开的RecyclerView

程序员文章站 2022-05-14 21:07:22
...

    由于项目需要,想要实现可以从中间展开的列表,网上照的大部分不符合心意,所以找了一个比较容易改的自己进行一些修改,是使用RecyclerView实现的,这个是项目地址

     先上效果图:

    从中间展开的RecyclerView

接下来是主要的修改部分,首先是BaseViewHolder:

在原来的基础上加上了VIEW_TYPE_FOOTER的类型以及getFooterViewResId()的抽象方法。

public BaseViewHolder(Context ctx, View itemView, int viewType) {
        super(itemView);
        mContext = ctx;
        switch (viewType) {
            case VIEW_TYPE_PARENT:
                groupView = (ViewGroup)itemView.findViewById(getGroupViewResId());
                arrow = (ImageView) itemView.findViewById(R.id.holder_arrow);
                break;
            case VIEW_TYPE_CHILD:
                childView = (ViewGroup) itemView.findViewById(getChildViewResId());
                break;
            case VIEW_TYPE_FOOTER:
                footerView = (ViewGroup)itemView.findViewById(getFooterViewResId());
                break;
         
        }
    }

    /**
     * return ChildView root layout id
     */
    public abstract int getChildViewResId();

    /**
     * return GroupView root layout id
     * */
    public abstract int getGroupViewResId();

    /**
     * return FooterView root layout id
     * */
    public abstract int getFooterViewResId();

在GroupItem中加上是否为底部的判断以及实现Cloneable接口:

public class GroupItem<T,S> extends BaseItem implements Cloneable{

    /**head data*/
    private T groupData;

    /** childDatas*/
    private List<S> childDatas;

    /** 是否展开,  默认展开*/
    private boolean isExpand = true;

    private boolean isFooter = false;

    /** 返回是否是父节点*/
    @Override
    public boolean isParent() {
        return true;
    }

    public boolean isExpand(){
        return isExpand;
    }

    public void onExpand() {
        isExpand = !isExpand;
    }

    public boolean isFooter() {
        return isFooter;
    }

    public void setFooter(boolean footer) {
        isFooter = footer;
    }

    public GroupItem(T groupData, List<S> childDatas, boolean isExpand) {
        this.groupData = groupData;
        this.childDatas = childDatas;
        this.isExpand = isExpand;
    }

    public boolean hasChilds(){
        if(getChildDatas() == null || getChildDatas().isEmpty() ){
            return false;
        }
        return true;
    }

    public List<S> getChildDatas() {
        return childDatas;
    }

    public void setChildDatas(List<S> childDatas) {
        this.childDatas = childDatas;
    }

    public void removeChild(int childPosition){

    }

    public T getGroupData() {
        return groupData;
    }

    @Override
    public Object clone(){
        try {
            return super.clone();
        }catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

接着在BaseRecyclerViewAdapter进行修改,首先在getItemViewType方法以及onCreateViewHolder方法中添加类型:

@Override
    public int getItemViewType(int position) {
        if (showingDatas.get(position) instanceof GroupItem) {
            if (((GroupItem) showingDatas.get(position)).isFooter()) {
                return BaseViewHolder.VIEW_TYPE_FOOTER;
            } else {
                return BaseViewHolder.VIEW_TYPE_PARENT;
            }
        } else {
            return BaseViewHolder.VIEW_TYPE_CHILD;
        }
    }

    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = null;
        switch (viewType) {
            case BaseViewHolder.VIEW_TYPE_PARENT:
                view = getGroupView(parent);
                break;
            case BaseViewHolder.VIEW_TYPE_CHILD:
                view = getChildView(parent);
                break;
            case BaseViewHolder.VIEW_TYPE_FOOTER:
                view = getFooterView(parent);
                break;
        }
        return createRealViewHolder(mActivity, view, viewType);
    }

在setShowingDatas方法中添加头部数据,这里我直接使用父布局的数据

/**
     * setup showing datas
     */
    private void setShowingDatas() {
        if (null != showingDatas) {
            showingDatas.clear();
        }
        if (this.childDatas == null) {
            this.childDatas = new ArrayList<>();
        }
        childDatas.clear();
        GroupItem groupItem;
        GroupItem footerItem;
        for (int i = 0; i < allDatas.size(); i++) {
            if (allDatas.get(i).getGroupItem() instanceof GroupItem) {
                groupItem = allDatas.get(i).getGroupItem();
            } else {
                break;
            }
            childDatas.add(i, groupItem.getChildDatas());
            showingDatas.add(groupItem);
            if (groupItem.hasChilds() && groupItem.isExpand()) {
                showingDatas.addAll(groupItem.getChildDatas());
            }
            if (showFooter()) {
                footerItem = (GroupItem) groupItem.clone();
                footerItem.setFooter(true);
                showingDatas.add(footerItem);
            }
        }
    }
 /**
     * 如果要有底部布局的话,该方法要返回true;
     *
     * @return value
     */
    public boolean showFooter(){
        return false;
    }

接着onBindViewHolder方法在中进行实例化

 @Override
    public void onBindViewHolder(final VH holder, final int position) {
        final Object item = showingDatas.get(position);
        final int gp = getGroupPosition(position);
        final int cp = getChildPosition(gp, position);
        if (item != null && item instanceof GroupItem) {
            if (((GroupItem) item).isFooter()) {
                onBindFooterHolder(holder, gp, position, (T) ((GroupItem) item).getGroupData());
            } else {
                onBindGroupHolder(holder, gp, position, (T) ((GroupItem) item).getGroupData());
                holder.groupView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (null != itemClickListener) {
                            itemClickListener.onGroupItemClick(position, gp, holder.groupView, ((GroupItem) item).isExpand());
                        }
                        if (((GroupItem) item).isExpand()) {
                            collapseGroup(position);
                        } else {
                            expandGroup(position);
                        }

                    }
                });
                holder.groupView.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {
                        if (null != itemLongClickListener) {
                            itemLongClickListener.onGroupItemLongClick(position, gp, holder.groupView);
                        }
                        return true;
                    }
                });
            }

        } else {
            onBindChildHolder(holder, gp, cp, position, (S) item);
            holder.childView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (null != itemClickListener) {
                        itemClickListener.onChildItemClick(position, gp, cp, holder.childView);
                    }
                }
            });
            holder.childView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    if (null != itemLongClickListener) {
                        int gp = getGroupPosition(position);
                        itemLongClickListener.onChildItemLongClick(position, gp, cp, holder.childView);
                    }
                    return true;
                }
            });
        }
    }

最后是使用:

public class MiddleAdapter extends BaseRecyclerViewAdapter<ExpandData.ParentData,ExpandData.ChildData,MiddleAdapter.MiddleViewHolder> implements OnRecyclerViewListener.OnItemClickListener{

    private LayoutInflater mInflater;

    public MiddleAdapter(Activity activity, BaseRecyclerData data) {
        super(activity, data);
        mInflater = LayoutInflater.from(activity);
        setOnItemClickListener(this);
    }

    @Override
    public View getGroupView(ViewGroup parent) {
        return mInflater.inflate(R.layout.viewholder_parent, parent, false);
    }

    @Override
    public View getChildView(ViewGroup parent) {
        return mInflater.inflate(R.layout.viewholder_child, parent, false);
    }

    @Override
    public View getFooterView(ViewGroup parent) {
        return mInflater.inflate(R.layout.viewholder_footer, parent, false);
    }

    @Override
    public MiddleViewHolder createRealViewHolder(Context ctx, View view, int viewType) {
        return new MiddleViewHolder(ctx,view,viewType);
    }

    @Override
    public void onBindGroupHolder(MiddleViewHolder holder, int groupPos, int position, ExpandData.ParentData groupData) {
        holder.setText(R.id.holder_title,groupData.title);
    }

    @Override
    public void onBindFooterHolder(MiddleViewHolder holder, int groupPos, int position, ExpandData.ParentData groupData) {
        holder.setImage(R.id.holder_image,R.mipmap.icon_shoes);
    }

    @Override
    public void onBindChildHolder(MiddleViewHolder holder, int groupPos, int childPos, int position, ExpandData.ChildData childData) {
        holder.setText(R.id.holder_content,childData.content);
    }

    @Override
    public void onGroupItemClick(int position, int groupPosition, View view, boolean isExpand) {

    }

    @Override
    public void onChildItemClick(int position, int groupPosition, int childPosition, View view) {

    }

    @Override
    public boolean showFooter() {
        return true;
    }

    class MiddleViewHolder extends BaseViewHolder {

        MiddleViewHolder(Context ctx, View itemView, int viewType) {
            super(ctx, itemView, viewType);
        }

        @Override
        public int getChildViewResId() {
            return R.id.holder_child;
        }

        @Override
        public int getGroupViewResId() {
            return R.id.holder_parent;
        }

        @Override
        public int getFooterViewResId() {
            return R.id.holder_footer;
        }


        void setImage(int resId, int imgId){
            ImageView imageView = (ImageView) itemView.findViewById(resId);
            imageView.setImageResource(imgId);
        }

        void setText(int resId, String str){
            TextView textView = (TextView) itemView.findViewById(resId);
            textView.setText(str);
        }
    }
}

附上下载地址

补充个GitHub地址

相关标签: RecyclerView