万能适配器

来源:互联网 发布:深圳程序员培训机构 编辑:程序博客网 时间:2024/04/30 06:42

为何要使用万能适配器?

在安卓开发中,用到ListView和GridView的地方很多,如果你是开发一个简单点的APP还好,可能ListView和GridView的数量不会太多,我们只要去写几个BaseAdapter实现类就可以了。但如果有一天,你需要开发一个APP里面具有几十个ListView的子页面,此时的你该怎么办?每个ListView或GridView都去写一个适配的Adatper类吗?
这个时候就要想办法让自己减少很多工作量,避免做重复无意义劳动。

概念

就像上面说的我们每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里我们就抽取出两个类分别是CommonViewHolder和CommonAdapter来存放相同的东西。 好了,废话不多说,直接上代码。

第一步抽取出通用ViewHolder:

/** * 通用的ViewHolder * 照顾下初次使用SparseArray 其实它是Android推荐使用的一个优化容器,相当于一个Map<integer,View>    * 目的是为了提供效率,其核心算法是折半查找,其用法和Map无两异。 *  Created by lx_yoyo on 2016/8/10. */public class CommonViewHolder {    private SparseArray<View> mViews;    private View  mConvertView;    private CommonViewHolder(Context context, ViewGroup parent,int layoutId,int position) {        this.mViews = new SparseArray<>();        mConvertView = LayoutInflater.from(context).inflate(layoutId,parent,false);        mConvertView.setTag(this);    }    /**     * 拿到一个ViewHolder对象     * @param context 上下文     * @param convertView 视图view     * @param parent 容器     * @param layoutId 布局layoutID     * @param position 当前索引     * @return     */    public static CommonViewHolder get(Context context, View convertView,                                 ViewGroup parent, int layoutId, int position)    {        if (convertView == null)        {            return new CommonViewHolder(context, parent, layoutId, position);        }        return (CommonViewHolder) convertView.getTag();    }    /**     * 通过控件的Id获取对于的控件,如果没有则加入views     * @param viewId     * @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;    }    public View getConvertView()    {        return mConvertView;    }}

第二步抽取Adapter:

/** *通用Adapter * Created by lx_yoyo on 2016/8/10. */public abstract class CommonAdapter<T> extends BaseAdapter {    protected LayoutInflater mInflater;    protected Context mContext;    protected List<T> mDatas;    protected final int mItemLayoutId;    public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId)    {        this.mContext = context;        this.mInflater = LayoutInflater.from(mContext);        this.mDatas = mDatas;        this.mItemLayoutId = itemLayoutId;    }    @Override    public int getCount()    {        return mDatas.size();    }    @Override    public T getItem(int position)    {        return mDatas.get(position);    }    @Override    public long getItemId(int position)    {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent)    {        final CommonViewHolder viewHolder = getViewHolder(position, convertView,                parent);        convert(viewHolder, getItem(position));        return viewHolder.getConvertView();    }    public abstract void convert(CommonViewHolder helper, T t);    private CommonViewHolder getViewHolder(int position, View convertView,                                     ViewGroup parent)    {        return CommonViewHolder.get(mContext, convertView, parent, mItemLayoutId,                position);    }}

第三步就是Activity调用:

......private List<Bean> mDatas = new ArrayList<>(); @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        ListView listView = (ListvView)findViewById(R.id.Listview);         listView.setAdapter(new CommonAdapter<Bean>(getApplicationContext(),mDatas,R.layout.list_item) {            @Override            public void convert(CommonViewHolder helper, Joke.ShowapiResBodyBean.ContentlistBean item) {                //在这里就写item中的控件以及赋值                TextView titleText = helper.getView(R.id.text_title);                titleText.setText(item.getTitle());                TextView contentText = helper.getView(R.id.text_content);                contentText.setText(item.getText());            }        } );    }......

以上就是一个万能适配器了,像CommonAdapter和CommonViewHolder基本上也不需要变动了,一劳永逸。
像上面简单控件赋值的话可以直接写在Activity里面,如比较复杂的item的话单独写个适配器,但不需要再
去继承BaseAdapter了,直接继承CommonAdapter配合CommonViewHolder就可以了。这样使代码量减少了很多。

当然以上代码还可以更简化一点,就是把这些ViewHolder.getView和setText,setImage等方法再一次封装,变成只传递控件Id和对应数据就够了,这样一来我们连类都不需要写了,直接用new对象去写个内部类实现就可以了。

代码如下:

/** *这里只写文字和图片的,如还需什么的自己去加就可以了  */public class CommonViewHolder {    ......     /**      * 为TextView设置字符串      *       * @param viewId      * @param text      * @return      */      public CommonViewHolder setText(int viewId, String text)      {          TextView view = getView(viewId);          view.setText(text);          return this;      }      /**      * 为ImageView设置图片      *       * @param viewId      * @param drawableId      * @return      */      public CommonViewHolder setImageResource(int viewId, int drawableId)      {          ImageView view = getView(viewId);          view.setImageResource(drawableId);          return this;      }      /**      * 为ImageView设置图片      *       * @param viewId      * @param drawableId      * @return      */      public CommonViewHolder setImageBitmap(int viewId, Bitmap bm)      {          ImageView view = getView(viewId);          view.setImageBitmap(bm);          return this;      }      /**      * 为ImageView设置图片      *       * @param viewId      * @param drawableId      * @return      */      public CommonViewHolder setImageByUrl(int viewId, String url)      {          ImageLoader.getInstance(3, Type.LIFO).loadImage(url,                  (ImageView) getView(viewId));          return this;      }      ......}

现在在Activity只需要这么写:

......private List<Bean> mDatas = new ArrayList<>(); @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        ListView listView = (ListvView)findViewById(R.id.Listview);         listView.setAdapter(new CommonAdapter<Bean>(getApplicationContext(),mDatas,R.layout.list_item) {            @Override            public void convert(CommonViewHolder helper, Bean item) {                //在这里就写item中的控件以及赋值                helper.setText(R.id.id.text_title,item.getTitle())                      .setText(R.id.text_content,item.getText);            }        } );    }......

到此,Android 打造万能的ListView GridView 适配器结束;
源码地址:点击下载万能适配器
谢谢!!!

0 0
原创粉丝点击