美文网首页
打造listview通用的Adapter

打造listview通用的Adapter

作者: AJI大侠 | 来源:发表于2017-11-06 17:17 被阅读15次

    叙述

    1.在Android开发中写Adapter是一件枯燥重复的工作。 对于Adapter一般都继承BaseAdapter写几个方法,getView里面用ViewHolder存储,这里我做一次Adapter封装,打造一个通用的Adapter,想写下来也是为了方便日后的查看,当然这里我们不谈
    RecyclerView

    下面是一段常用写法,每次都写到我想吐,一看到列表就想起了BaseAdapter - -!

    public class HomeAdapter extends BaseAdapter
    {
        private Context mContext;
        private List<HomeBean> homeBeanList;
        private LayoutInflater layoutInflater;
    
        public HomeAdapter(Context mContext, List<HomeBean> homeBeanList)
        {
            this.layoutInflater = LayoutInflater.from(mContext);
            this.mContext = mContext;
            this.homeBeanList = homeBeanList;
        }
    
        @Override
        public int getCount()
        {
            if(homeBeanList == null || homeBeanList.size() <= 0)
            {
                return 0;
            }
            return homeBeanList.size();
        }
    
        @Override
        public Object getItem(int position)
        {
    
            return homeBeanList.get(position);
        }
    
        @Override
        public long getItemId(int position)
        {
            return position;
        }
    
        public void refresh(List<HomeBean> datas)
        {
            if (datas == null)
            {
                datas = new ArrayList<>(0);
            }
            this.homeBeanList = datas;
            notifyDataSetChanged();
        }
    
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            ViewHodler viewHodler = null;
            HomeBean homeBean = homeBeanList.get(position);
            if (convertView == null)
            {
                viewHodler = new ViewHodler();
                convertView = layoutInflater.inflate(R.layout.home_item , parent , false);
                viewHodler.home_item_icon = convertView.findViewById(R.id.home_item_icon);
                viewHodler.home_item_text = convertView.findViewById(R.id.home_item_text);
                viewHodler.home_item_price = convertView.findViewById(R.id.home_item_price);
                convertView.setTag(viewHodler);
            }
            else
            {
                viewHodler = (ViewHodler) convertView.getTag();
            }
            ImageLoadUtils.loadImage(mContext , homeBean.getImageUrl().getUrl() , viewHodler.home_item_icon);
            viewHodler.home_item_text.setText(homeBean.getTitle());
          viewHodler.home_item_price.setText(homeBean.getPrice());
            return convertView;
        }
    
        public static class ViewHodler
        {
            private TextView home_item_text;
            private TextView home_item_price;
            private ImageView home_item_icon;
    
        }
    
    }
    
    • 这一种写法相信大家都写的很熟了,我就不多说了下面我们看看如何写通用的adapter
      1.新建一个class,写好通用的HodlerView,代码如下
       public class FuHodlerView
    {
        private final SparseArray<View> mViews;
        private final int mPositiom;
        private final View mConvertView;
    
        public FuHodlerView(ViewGroup parent , int layoutId , int position)
        {
            this.mPositiom = position;
            mViews = new SparseArray<>();
            mConvertView = LayoutInflater.from(parent.getContext()).inflate(layoutId , parent , false);
            // setTag()
            mConvertView.setTag(this);
        }
    
        /**
         * 拿到全部的views
         * @return
         */
        public SparseArray<View> getAllViews()
        {
            return mViews;
        }
    
        /**
         *  拿到一个viewHodler对象
         * @param convertView
         * @param parent
         * @param layoutId
         * @param position
         * @return
         */
        public static FuHodlerView get(View convertView , ViewGroup parent , int layoutId , int position)
        {
            if(convertView == null)
            {
                return new FuHodlerView(parent , layoutId ,position);
            }
            else
            {
                return (FuHodlerView) convertView.getTag();
            }
        }
    
        public View getConvertView()
        {
            return mConvertView;
        }
    
        /**
         * 通过控件的Id获取对于的控件,如果没有则加入views
         * @param viewId
         * @param <T>
         * @return
         */
        public <T extends View> T getView(int viewId)
        {
           View view = mViews.get(viewId);
           if(view == null)
           {
               view = mConvertView.findViewById(viewId);
           }
           mViews.put(viewId , view);
           return (T) view;
        }
    
        /**
         * 为TextView设置字符串
         * @param viewId
         * @param text
         * @return
         */
        public FuHodlerView setText(int viewId , CharSequence text)
        {
            TextView textView = getView(viewId);
            textView.setText(text);
            return this;
        }
    
        /**
         * 为Imageview设置本地图片
         * @param viewId
         * @param drawableId
         * @return
         */
        public FuHodlerView setImageResource(int viewId , int drawableId)
        {
            ImageView imageView = getView(viewId);
            imageView.setImageResource(drawableId);
            return this;
        }
    
    
        /**
         * 为Imageview设置网络图片
         * @param viewId
         * @param url
         * @return
         */
        public FuHodlerView setImageByUrl(Context context ,int viewId , String url)
        {
            ImageView imageView = getView(viewId);
            ImageLoadUtils.loadImage(context , url , imageView);
            return this;
        }
    
        public int getPositiom()
        {
            return mPositiom;
        }
    
    }
    

    -代码注释的很清楚,大家可以自己看,我主要说的是这里用到了-SparseArray缓存我们itemView内部的子View,这样可以得到一个通用的ViewHolder,每次要创建ViewHolder的时候只需要传入我们的layoutId即可。
    2.有了ViewHolder,下面我们就可以打造通用的adapter了,代码如下:

    public abstract class FuBaseAdapter<T> extends BaseAdapter implements AbsListView.OnScrollListener
    {
        protected Collection<T> mDatas;
        private final int mItemLayoutId;
        private AbsListView mListView;
        // 是否在滑动
        private boolean isScrolling;
        private Context mContext;
        private LayoutInflater inflater;
        private AbsListView.OnScrollListener listener;
    
        public FuBaseAdapter(AbsListView listView , Collection<T> mDatas , int mItemLayoutId)
        {
            if(mDatas == null)
            {
                mDatas = new ArrayList<>(0);
            }
            this.mDatas = mDatas;
            this.mListView = listView;
            this.mItemLayoutId = mItemLayoutId;
            mContext = listView.getContext();
            inflater = LayoutInflater.from(mContext);
            mListView.setOnScrollListener(this);
        }
    
        // 刷新数据
        public void refresh(Collection<T> mDatas)
        {
            if(mDatas == null)
            {
                mDatas = new ArrayList<>(0);
            }
            this.mDatas = mDatas;
            notifyDataSetChanged();
        }
    
        public void addOnScrollListener(AbsListView.OnScrollListener l)
        {
            this.listener = l;
        }
    
        @Override
        public int getCount()
        {
            if (mDatas == null || mDatas.size() <= 0)
            {
                return 0;
            }
            return mDatas.size();
        }
    
        @Override
        public T getItem(int position)
        {
            if (mDatas instanceof List)
            {
                return ((List<T>) mDatas).get(position);
            }
            else if (mDatas instanceof Set)
            {
                return new ArrayList<T>(mDatas).get(position);
            }
            else
            {
                return null;
            }
        }
    
        @Override
        public long getItemId(int position)
        {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            final FuHodlerView fuHodlerView = getViewHodler(position , convertView ,parent);
            convert(fuHodlerView , getItem(position) , isScrolling ,position);
            return fuHodlerView.getConvertView();
        }
    
        public FuHodlerView getViewHodler(int position , View convertView , ViewGroup parent)
        {
            return FuHodlerView.get(convertView , parent , mItemLayoutId , position);
        }
    
        public void convert(FuHodlerView helper , T item , boolean isScrolling)
        {
        }
    
        public void convert(FuHodlerView helper , T item , boolean isScrolling , int position)
        {
            convert(helper, getItem(position), isScrolling);
        }
    
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState)
        {
            // 当前没有滚动的时候
            if(scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)
            {
                isScrolling = false;
                this.notifyDataSetChanged();
            }
            else
            {
                isScrolling = true;
            }
    
            if(listener != null)
            {
                listener.onScrollStateChanged(view , scrollState);
            }
        }
    
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
        {
            if(listener != null)
            {
                listener.onScroll(view , firstVisibleItem , visibleItemCount , totalItemCount);
            }
        }
    }
    

    -在这里我继承了OnScrollListener,这里主要是为了做一个优化即滚动时不加载图片
    3.最关键的时候到了,怎使用呢只需继承我们通用的Adapter,请看代码,代码是最好的老师

    public class HomeFuAdapter extends FuBaseAdapter<HomeBean>
    {
    
        public HomeFuAdapter(AbsListView listView, List<HomeBean> mDatas)
        {
            super(listView, mDatas, R.layout.home_item);
        }
    
        @Override
        public void convert(FuHodlerView helper, HomeBean item, boolean isScrolling)
        {
            Context context = helper.getConvertView().getContext();
            if(isScrolling)
            {
                ImageView imageView = helper.getView(R.id.home_item_icon);
                ImageLoadUtils.loadImage(context , item.getImageUrl().getUrl() ,imageView);
            }
            else
            {
                helper.setImageByUrl(context , R.id.home_item_icon , item.getImageUrl().getUrl());
            }
    
            helper.setText(R.id.home_item_text , item.getTitle());
            helper.setText(R.id.home_item_price , item.getPrice());
        }
    }
    

    -大功告成简简单单的几行代码搞定,然后在Activity里面new HomeFuAdapter......这么简单我就不写了小伙伴们自己可以搞定的,剩下的时间可以在QQ群和一群群友们吹吹水聊聊天了!

    相关文章

      网友评论

          本文标题:打造listview通用的Adapter

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