美文网首页Android UI术与道
AndroidUI初探②RecyclerView.Adapter

AndroidUI初探②RecyclerView.Adapter

作者: 逝我 | 来源:发表于2017-02-15 12:20 被阅读92次

    前言

    早期文章 , 如今搬运过来 , RecyclerView用法相信都会,这里主要介绍一下简单的封装。

    不管我们是在使用早期的ListView还是使用强大的RecyclerView ,我们都需要去实现其控件的Adapter ,将数据与控件绑定起来 。不管是ListViewAdapter还是RecyclerViewAdapter ,都需要我们实现大量的方法 ,重复的去编写相同的操作 ,为了减少不必要的编码 ,就需要将Adapter的共性抽取出来 ,做成一个通用的Adapter ,以后需要实现Adapter ,只需要继承我们自己写的Adapter就OK了 。

    分析

    不管是我们的ListViewAdapter还是RecyclerViewAdapter ,其主要有两点 :
    第一、 外界提供给我们的数据源 , 这个是变化的 。
    第二、 外界提供给我们的布局文件资源(也可拓展为布局View) , 这个也是变化,需要传递的参数
    另 : RecyclerView需要我们自己实现Item的各种事件
    如果布局中需要Context ,也可以作为参数传入 ,创建多个构造函数

    编写 :

    要封装RecyclerView.Adapter,就需要搞清楚,RecyclerViewAdapter主要实现三个方法 ,onCreateViewHolderonBindViewHoldergetItemCount ,还有一个ViewHolder类 。我们来分析分析 , 这几个方法和类 。

    onCreateViewHolder

    主要构件RecyclerView每个Item布局对象 ,与ViewHolder关联 ,达到复用视图的效果,并传递给 onBindViewHolder ,因为我们的布局对象都是View , 所以这个地方 , 我们可以根据传递进来的资源文件infalter成一个View ,亦或是传进来的View,再与ViewHolder关联 , 此处我们就可以对外屏蔽掉了 。

    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
            View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
                    false);
            ViewHolder viewHolder = new ViewHolder(view);
    
            // 初始化Item事件监听
            initOnItemListener(viewHolder);
    
            return viewHolder;
        }
    
    

    onBindViewHolder

    主要讲数据与ViewHolder里面的控件相关联 ,因为我要实现不同RecyclerView Item的数据显示 ,所以这个地方不能写死 ,需要我们根据情况 ,将数据绑定到不同的控件上面 , 这里需要抽象方法传递出来数据 , 让继承我们的Adapter做操作

    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
        {
            Object o = mItems.get(position);
            convertView((ViewHolder) holder,o);
        }
    
    

    getItemCount

    
        @Override
        public int getItemCount()
        {
            return mItems.size();
        }
    
    

    返回我们的Item总条数

    ViewHolder

    将ViewHolder类抽取出来,主要是为了更加方便的进行View组件的操作,这个类 ,主要是为我们的控件复用服务 ,因为在Adapter每个Item与ViewHolder关联 ,所以在此类中 , 我们可以做一些获取控件的简便操作 。

        
            private View mConvertView;
            private SparseArray<View> mViews;
        
            public ViewHolder(View itemView)
            {
                super(itemView);
                mViews = new SparseArray<>() ;
                mConvertView = itemView ;
            }
        
            /**
             * 根据资源获取View对象
             * @param res
             * @param <T>
             * @return
             */
            public <T extends View> T getView(@IdRes int res) {
        
                View view = mViews.get(res);
                if (view == null) {
                    view = mConvertView.findViewById(res) ;
                    mViews.put(res,view);
                }
                return (T) view;
            }
    
    

    完整Adapter代码

    
        /**
         * Created by Zeno on 2016/6/8.
         *
         *  简介 :
         *      抽象类的抽取 ,主要是抽取一些有共性的方法和参数 。
         *
         *  分析:
         *      不管是ListView还是RecyclerView ,主要有两个点需要实现:
         *          第一 :外界提供的数据源
         *          第二 :外界提供的布局
         *      这两个点是明确从外部传入的 ,所以首先这两个点不能固定 ,需要作为参数从外部传入
         *      如果有一些资源需要用到上下文 ,还需要传入Context
         *
         *
         */
        public abstract class SimpleBaseRecyclerAdapter extends RecyclerView.Adapter
        {
            // each item layout res
            private int mItemLayoutRes;
            // total item data set
            private List<?> mItems;
        
            private ItemClickListener mItemClickListener ;
            private ItemLongClickListnener mItemLongClickListnener ;
        
            public SimpleBaseRecyclerAdapter(@LayoutRes int mItemLayoutRes, List<?> items)
            {
                this.mItemLayoutRes = mItemLayoutRes;
                // 如果没有传入的数据 ,则自动创建一个空的集合 ,防止报空指针
                this.mItems = items ==null ? new ArrayList<>() : items;
            }
        
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
            {
                View view = LayoutInflater.from(parent.getContext()).inflate(mItemLayoutRes, parent,
                        false);
                ViewHolder viewHolder = new ViewHolder(view);
        
                // 初始化Item事件监听
                initOnItemListener(viewHolder);
        
                return viewHolder;
            }
        
        
            @Override
            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
            {
                Object o = mItems.get(position);
                convertView((ViewHolder) holder,o);
            }
        
            @Override
            public int getItemCount()
            {
                return mItems.size();
            }
        
            public abstract void convertView(ViewHolder viewHolder, Object itemObj) ;
        
        
            /**
             * init set item view listener
             * @param holder
             */
            private void initOnItemListener(final RecyclerView.ViewHolder holder) {
                    if (mItemClickListener != null) {
                        holder.itemView.setOnClickListener(new View.OnClickListener()
                        {
                            @Override
                            public void onClick(View v)
                            {
                                Object o = mItems.get(holder.getLayoutPosition());
                                mItemClickListener.onItemClick(v,o ,holder.getLayoutPosition());
                            }
                        });
                    }
        
                    if (mItemLongClickListnener != null) {
                        holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
                        {
                            @Override
                            public boolean onLongClick(View v)
                            {
                                Object o = mItems.get(holder.getLayoutPosition());
                                mItemLongClickListnener.onItemLongClick(v,o,holder.getLayoutPosition());
                                return true;
                            }
                        });
                    }
            }
        
            /**
             * set item view click
             * @param listener
             */
            public void setOnItemClickListener(ItemClickListener listener) {
                mItemClickListener = listener ;
            }
        
            /**
             * set item view long click
             * @param listener
             */
            public void setOnItemLongClickListener(ItemLongClickListnener listener) {
                mItemLongClickListnener = listener ;
            }
        
        
            public interface ItemClickListener {
                void onItemClick(View view ,Object itemObj , int position) ;
            }
        
            public interface ItemLongClickListnener {
                void onItemLongClick(View view ,Object itemObj, int position) ;
            }
        }
    
    
    

    完整ViewHolder代码

    
        /**
         * Created by Zeno on 2016/6/8.
         *
         * ViewHolder主要是做一些与控件布局有关的操作 ,所有我们可以在这边简化一下获取控件对象的代码
         */
        public class ViewHolder extends RecyclerView.ViewHolder
        {
            private View mConvertView;
            private SparseArray<View> mViews;
        
            public ViewHolder(View itemView)
            {
                super(itemView);
                mViews = new SparseArray<>() ;
                mConvertView = itemView ;
            }
        
            /**
             * 根据资源获取View对象
             * @param res
             * @param <T>
             * @return
             */
            public <T extends View> T getView(@IdRes int res) {
        
                View view = mViews.get(res);
                if (view == null) {
                    view = mConvertView.findViewById(res) ;
                    mViews.put(res,view);
                }
                return (T) view;
            }
        
            /**
             * 提供TextView和Button设置文本简化操作
             * @param idRes
             * @param charSequence
             * @return
             */
            public ViewHolder setText(@IdRes int idRes , CharSequence charSequence) {
                View view = getView(idRes);
                if (view instanceof TextView) {
                    ((TextView)view).setText(charSequence);
                }else if (view instanceof Button) {
                    ((Button)view).setText(charSequence);
                }
        
                return this ;
            }
        
            /**
             * 提供TextView和Button设置文本颜色简化操作
             * @param idRes
             * @param color
             * @return
             */
            public ViewHolder setTextColor(@IdRes int idRes , int color) {
                View view = getView(idRes);
                if (view instanceof TextView) {
                    ((TextView)view).setTextColor(color);
                }else if (view instanceof Button) {
                    ((Button)view).setTextColor(color);
                }
                return this ;
            }
        
        
            /**
             * 设置指定ViewId的背景颜色
             * @param idRes
             * @param color
             * @return
             */
            public ViewHolder setBackgroundColor(@IdRes int idRes , int color) {
        
                View view = getView(idRes);
                view.setBackgroundColor(color);
        
                return this;
            }
        
            /**
             * 设置ImageView显示图片
             * @param idRes
             * @param res
             * @return
             */
            public ViewHolder setImageResoruce(@IdRes int idRes , @DrawableRes int res) {
                View view = getView(idRes);
                if (view instanceof ImageView) {
                    ((ImageView)view).setImageResource(res);
                }
        
                return this ;
            }
        
            /**
             * 设置指定控件ID的点击事件
             * @param idRes
             * @param listener
             * @return
             */
            public ViewHolder setOnClickListener(@IdRes int idRes , View.OnClickListener listener) {
        
                View view = getView(idRes);
                view.setOnClickListener(listener);
        
                return this;
            }
        
            /**
             * 设置指定控件ID的长按事件
             * @param idRes
             * @param listener
             * @return
             */
            public ViewHolder setOnLongClickListener(@IdRes int idRes , View.OnLongClickListener listener) {
                View view = getView(idRes);
                view.setOnLongClickListener(listener);
        
                return this;
            }
        
            /**
             * 设置指定控件的TAG
             * @param idRes
             * @param tag
             * @return
             */
            public ViewHolder setTag(@IdRes int idRes , Object tag) {
                View view = getView(idRes);
                view.setTag(tag);
        
                return this;
            }
        
            /**
             * 获取指定控件的TAG
             * @param idRes
             * @return
             */
            public Object getTag(@IdRes int idRes) {
                View view = getView(idRes);
                return  view.getTag() ;
            }
        
        }
    
    
    

    相关文章

      网友评论

        本文标题:AndroidUI初探②RecyclerView.Adapter

        本文链接:https://www.haomeiwen.com/subject/jucqwttx.html