当前位置:网站首页>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.

   

原网站

版权声明
本文为[Xie Dong_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/221/202208091203557607.html