万能适配器实战

原创 2015年07月06日 16:47:44

今天带来鸿洋大神的万能适配器实战。我们当然不想在项目中每个activity中遇到ListView、GridView就自定义个适配器。万能适配器可以帮我们减少代码的编写量,也能让项目更精炼!话不多说,如果你还没有使用万能适配器,那么赶紧的!

先上今天实现的效果图:
这里写图片描述

关键点:
1.ViewHolder类。利用SparseArray来存储布局中的每个view。主要方法:

  • get(Context context,View convertView,
    ViewGroup parent,int layoutId,int position)

  • getView(int viewId)

2.CommonAdapter类。利用泛型实现任何对象类型绑定。主要方法:

  • convert(ViewHolder helper,T item)

下面给出项目具体实现,图片加载用的是Universal-ImageLoader开源框架,如果有同学感兴趣,可以看之前的一篇文章Universal-Image-Loader加载listView中图片

一.ViewHolder类。功能:

  • 添加了setImageByUrl(int viewId,String url)方法,通过ImageLoader加载图片
  • 这里其实可以实现我们在item中需要的很多方法
/**
 * Created by ${wj} ,
 * on 2015/7/6 0006.
 */
public class ViewHolder {

    private SparseArray<View> mViews;//每个Item的view
    private int mPosition;
    private View mContentView;

    private ImageLoader mImageLoader=ImageLoader.getInstance();

    /**
     * 构造器
     * @param context
     * @param parent
     * @param layoutId
     * @param position
     */
    private ViewHolder(Context context,ViewGroup parent,int layoutId,int position){
        this.mPosition=position;
        this.mViews=new SparseArray<View>();
        mContentView=LayoutInflater.from(context).inflate(layoutId,parent,false);
        //setTag
        mContentView.setTag(this);
    }

    /**
     * 拿到一个ViewHolder对象
     */
    public static ViewHolder get(Context context,View convertView,
                                 ViewGroup parent,int layoutId,int position){
        if(convertView==null){
            return new ViewHolder(context,parent,layoutId,position);
        }

        return (ViewHolder) convertView.getTag();
    }

    /**
     * 获取当前item对象
     * @return
     */
    public View getConvertView(){
        return mContentView;
    }

    /**
     * 通过控件的id获取对应的控件,如果没有则加入views
     * @param viewId
     * @param <T>
     * @return
     */
    public <T extends View> T getView(int viewId){

        View view=mViews.get(viewId);//先从容器中获取

        if(view==null){
            view=mContentView.findViewById(viewId);
            mViews.put(viewId,view);//放入容器中
        }

        return (T)view;
    }

    /**
     * 为TextView设置字符串
     * @param viewId
     * @param text
     * @return
     */
    public ViewHolder setText(int viewId,String text){
        TextView view=getView(viewId);
        view.setText(text);
        return this;
    }

    /**
     * 为ImageView设置图片
     * @param viewId
     * @param bm
     * @return
     */
    public ViewHolder setImageBitmap(int viewId,Bitmap bm){
        ImageView iv=getView(viewId);
        iv.setImageBitmap(bm);
        return this;
    }

    /**
     * 为ImageView设置图片(ImageLoader网络加载)
     * @param viewId
     * @param url
     * @return
     */
    public ViewHolder setImageByUrl(int viewId,String url){

        /**
         * ImageLoader 参数
         */
        DisplayImageOptions options=new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.shishi)
                .showImageForEmptyUri(R.drawable.shishi)
                .cacheInMemory(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .displayer(new RoundedBitmapDisplayer(20))
                .build();

        mImageLoader.displayImage(url, (ImageView) getView(viewId),options);
        return this;
    }

    /**
     * 获取当前item角标
     * @return
     */
    public int getPosition(){
        return mPosition;
    }

}

二、CommonAdapter
其实主要方法就是对外开发的corvert方法

/**
 * Created by ${wj} ,
 * on 2015/7/6 0006.
 */
public abstract class CommonAdapter<T> extends BaseAdapter{

    protected LayoutInflater mInflater;
    protected Context mContext;
    protected List<T> mDatas;//泛型list数据,可以适配所有对象类型
    protected final int mItemLayoutId;

    /**
     * 构造器
     * @param mDat需要显示的数据集合
     * @param mCont上下文
     * @param mItemLayoutI子布局文件
     */
    public CommonAdapter(List<T> mDatas, Context mContext, int mItemLayoutId) {
        this.mDatas = mDatas;
        this.mContext = mContext;
        this.mItemLayoutId = mItemLayoutId;

        this.mInflater=LayoutInflater.from(mContext);
    }

    @Override
    public int getCount() {
        return mDatas.size();
    }

    @Override
    public Object 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 ViewHolder viewHolder=getViewHolder(position,convertView,parent);
        convert(viewHolder,(T)getItem(position));
        return viewHolder.getConvertView();
    }

    /**
     * 抽取出getView中间改变的部分
     * @param helper    holder缓存对象
     * @param item      Bean对象
     */
    public abstract void convert(ViewHolder helper,T item);

    /**
     * 根据我们的ViewHolder类,获取viewHolder对象
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    private ViewHolder getViewHolder(int position,View convertView,ViewGroup parent){
        return ViewHolder.get(mContext,convertView,parent,mItemLayoutId,position);
    }

}

三、MainActivity中使用

 private ListView strList;
    private List<Star> mDatas=new ArrayList<>();

    private CommonAdapter<Star> mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        strList= (ListView) findViewById(R.id.lv);

        //初始化数据
        initDatas();

        //实例化万能适配器
        mAdapter=new CommonAdapter<Star>(mDatas,getApplicationContext(),R.layout.item_3) {
            @Override
            public void convert(ViewHolder helper, Star item) {
                helper.setText(R.id.item_name,item.getName());
                helper.setText(R.id.item_describ,item.getDescrib());
                helper.setImageByUrl(R.id.item_img,item.getImgUrl());
            }
        };
        //listView绑定适配器
        strList.setAdapter(mAdapter);
    }

数据来源

private void initDatas()
    {

        Star star = null;
        star = new Star("http://img0.imgtn.bdimg.com/it/u=1173327,3576718335&fm=11&gp=0.jpg",
                "AngleBaby","跑男团一号美女AngleBaby!");
        mDatas.add(star);
        star = new Star("http://img4.imgtn.bdimg.com/it/u=1750535930,1467743570&fm=21&gp=0.jpg",
                "邓超","跑男团老队长邓超!");
        mDatas.add(star);
        star = new Star("http://img5.imgtn.bdimg.com/it/u=1593808313,3868391842&fm=11&gp=0.jpg",
                "包贝尔","跑男团光头包贝尔!");
        mDatas.add(star);
        star = new Star("http://img2.imgtn.bdimg.com/it/u=2037429927,1919504819&fm=21&gp=0.jpg",
                "陈赫","跑男团一号贱男0.0陈赫!");
        mDatas.add(star);
        star = new Star("http://img2.imgtn.bdimg.com/it/u=3133077552,2769012996&fm=21&gp=0.jpg",
                "王祖蓝","跑男团金老师王祖蓝!");
        mDatas.add(star);
        star = new Star("http://img2.imgtn.bdimg.com/it/u=2137668625,2504210993&fm=21&gp=0.jpg",
                "郑凯","跑男团小猎豹郑凯!");
        mDatas.add(star);
    }

这里有一个简单的实体类Star

public class Star {
    private String imgUrl;
    private String name;
    private String describ;

    public Star(String imgUrl,String name,String describ) {
        this.describ = describ;
        this.imgUrl = imgUrl;
        this.name = name;
    }

    public String getDescrib() {
        return describ;
    }

    public void setDescrib(String describ) {
        this.describ = describ;
    }

    public String getImgUrl() {
        return imgUrl;
    }

    public void setImgUrl(String imgUrl) {
        this.imgUrl = imgUrl;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

剩下的就是MyApplication中实例化ImageLoader,并且配置MainActivity的Application名字,网络加载权限。

/**
 * Created by ${wj} on 2015/6/19 0019.
 */
public class MyApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();

        //创建默认的ImageLoader参数
        //ImageLoaderConfiguration configuration=ImageLoaderConfiguration.createDefault(this);

        //创建可以打印log的ImageLoaderConfiguration
        ImageLoaderConfiguration configuration=new ImageLoaderConfiguration.Builder(this)
                .writeDebugLogs()
                .memoryCache(new LruMemoryCache(2*1024*1024))//可以通过自己的内存缓存实现
                .memoryCacheSize(2 * 1024 * 1024)//内存缓存的最大值
                .memoryCacheSizePercentage(13)
                .build();

        //初始化ImageLoader
        ImageLoader.getInstance().init(configuration);
    }
}

OK,以上效果实现。需要源码的留言再贴吧,一般不需要了,哈哈!

Have a nice day!

版权声明:欢迎大家留言讨论

PowerfulRecyclerViewAdapter:一种RecyclerView的万能适配器实现

PowerfulRecyclerAdapter支持各种ViewHolder类型的RecyclerView.Adapter的实现,是一个万能适配器 项目地址:https://github.com/sim...
  • u012825445
  • u012825445
  • 2016年04月10日 15:09
  • 1082

一步步打造Android RecyclerView万能适配器

一步步打造RecyclerView万能适配器
  • u014702332
  • u014702332
  • 2016年12月21日 15:10
  • 843

Android开发之实现RecyclerView万能适配器

原文http://blog.csdn.net/u012551350/article/details/52026740,请看文章!
  • itluochen
  • itluochen
  • 2016年08月14日 20:37
  • 2858

android:打造万能通用适配器

本文原创,转载请注明出处。 1、前言 安卓项目中,listvie作为一个常见的控件,其适配器的写法是广大安卓开发者需要掌握和优化的技巧。 本文主要介绍一个通用的适配器BaseCommAdap...
  • q649381130
  • q649381130
  • 2016年06月29日 18:18
  • 7290

android万能适配器之SuperAdapter

对于传统的Adapter的写法,相信大家都是很熟悉的,然而在一个大型的项目中,我们肯定不会每次都去继承BaseAdapter,这样会很大的增加我们的劳动量,这里给大家介绍一个比较牛的SuperAdap...
  • u013424496
  • u013424496
  • 2016年04月28日 15:53
  • 3066

RecyclerView的基本使用、RecyclerView万能adapter及多条目的实现

RecyclerView是android5.0以后出现的一个Material Design风格的控件,可以用来实现Listview、GridView、瀑布流等效果;RecyclerView的基本使用 ...
  • wangwo1991
  • wangwo1991
  • 2017年08月18日 19:43
  • 186

RecyclerView的万能适配器

public abstract class CommandRecyclerAdapter extends RecyclerView.Adapter{ private Context mCon...
  • flying_fish_wj
  • flying_fish_wj
  • 2017年05月03日 20:59
  • 221

Android 快速开发系列 打造万能的ListView GridView 适配器

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自【张鸿洋的博客】1、概述相信做Android开发的写得最...
  • lmj623565791
  • lmj623565791
  • 2014年08月28日 21:32
  • 137255

万能适配器CommonAdapter和ViewHolder

对于我们Android程序猿来说,listview算是最常见的控件之一了,当然listview是要和adapter配套使用的,下面我们就来看看常规的adapter操作  @Override pub...
  • wrm0013
  • wrm0013
  • 2015年08月13日 17:18
  • 663

Android打造listview万能适配器(上)

来自:http://www.imooc.com/learn/372 一般情况下我们要在listview控件上展示自定义的数据,我们需要定义一个listview,然后对每个listview设置一个适配...
  • hnyzwtf
  • hnyzwtf
  • 2015年12月31日 19:23
  • 2046
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:万能适配器实战
举报原因:
原因补充:

(最多只允许输入30个字)