从中间展开的RecyclerView

  • Post author:
  • Post category:其他


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



版权声明:本文为carryWorld原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。