commonAdapter

  • 简化大量重复代码
  • 支持多布局
  • 自定义图片加载
  • 常用数据操作
  • view复用
  • RecyclerView item 点击和长按事件

  

gradle依赖

dependencies {
    compile 'com.classic.adapter:commonadapter:1.2'
    //项目中使用到RecyclerView,需要添加依赖
    compile 'com.android.support:recyclerview-v7:23.4.0'
}

开始使用

ListView/GridView 使用示例

List<News> newsList = ...;
//单布局文件
listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(new CommonAdapter<News>(context,
    //item布局文件
    R.layout.item_none_picture, newsList ) {
    @Override public void onUpdate(BaseAdapterHelper helper, News item, int position) {
        //BaseAdapterHelper详细用法,见下方

        helper.setText(R.id.xxx, item.getTitle())
               //可实现ImageLoad接口,进行图片自定义加载方式,demo里面使用的Glide
              .setImageLoad(new GlideImageLoad())
              .setImageUrl(R.id.xxx,item.getCoverUrl());
    }
});

//多布局文件
private final class MultipleLayoutAdapter extends CommonAdapter<News>{

    public MultipleLayoutAdapter(Context context, int layoutResId, List<News> data) {
        super(context, layoutResId, data);
    }
    //多种布局重写此方法即可
    @Override public int getLayoutResId(News item, int position) {
        int layoutResId = -1;
        switch (item.getNewsType()){
            case News.TYPE_NONE_PICTURE: //布局样式一
                layoutResId = R.layout.item_none_picture;
                break;
            case News.TYPE_SINGLE_PICTURE: //布局样式二
                layoutResId = R.layout.item_single_picture;
                break;
            case News.TYPE_MULTIPLE_PICTURE: //布局样式三
                layoutResId = R.layout.item_multiple_picture;
                break;

            更多的布局样式 ...
        }
        return layoutResId;
    }

    @Override public void onUpdate(BaseAdapterHelper helper, News item, int position) {
        helper.setImageLoad(new GlideImageLoad());
        switch (item.getNewsType()){
            case News.TYPE_NONE_PICTURE: //布局样式一
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;
            case News.TYPE_SINGLE_PICTURE: //布局样式二
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;
            case News.TYPE_MULTIPLE_PICTURE: //布局样式三
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;

            更多的布局样式 ...
        }
    }
}

RecyclerView 使用示例

List<News> newsList = ...;
//单布局文件
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new DefaultItemAnimator());
newsAdapter = new NewsAdapter(this, R.layout.item_none_picture, newsList);
recyclerView.setAdapter(newsAdapter);

private class NewsAdapter extends CommonRecyclerAdapter<News>{

    public NewsAdapter(Context context, int layoutResId, List<News> data) {
        super(context, layoutResId, data);
    }

    @Override public void onUpdate(BaseAdapterHelper helper, News item, int position) {
        helper.setText(R.id.xxx, item.getTitle())
              .setImageLoad(new GlideImageLoad())
              .setImageUrl(R.id.xxx,item.getCoverUrl());
    }
}

//多布局文件
private final class MultipleLayoutAdapter extends CommonRecyclerAdapter<News>{

    public MultipleLayoutAdapter(Context context, int layoutResId, List<News> data) {
        super(context, layoutResId, data);
    }
    //多种布局重写此方法即可
    @Override public int getLayoutResId(News item, int position) {
        int layoutResId = -1;
        switch (item.getNewsType()){
            case News.TYPE_NONE_PICTURE: //布局样式一
                layoutResId = R.layout.item_none_picture;
                break;
            case News.TYPE_SINGLE_PICTURE: //布局样式二
                layoutResId = R.layout.item_single_picture;
                break;
            case News.TYPE_MULTIPLE_PICTURE: //布局样式三
                layoutResId = R.layout.item_multiple_picture;
                break;

            更多的布局样式 ...
        }
        return layoutResId;
    }

    @Override public void onUpdate(BaseAdapterHelper helper, News item, int position) {
        helper.setImageLoad(new GlideImageLoad());
        switch (item.getNewsType()){
            case News.TYPE_NONE_PICTURE: //布局样式一
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;
            case News.TYPE_SINGLE_PICTURE: //布局样式二
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;
            case News.TYPE_MULTIPLE_PICTURE: //布局样式三
                helper.setText(R.id.xxx, item.getTitle())
                      .setImageUrl(R.id.xxx,item.getCoverUrl());
                break;

            更多的布局样式 ...
        }
    }
}

RecyclerView item点击事件和长按事件

commonRecyclerAdapter.setOnItemClickListener(new CommonRecyclerAdapter.OnItemClickListener() {
    @Override
    public void onItemClick(RecyclerView.ViewHolder viewHolder, View view, int position) {
        // TODO ...
    }
});
commonRecyclerAdapter.setOnItemLongClickListener(new CommonRecyclerAdapter.OnItemLongClickListener() {
    @Override public void onItemLongClick(RecyclerView.ViewHolder viewHolder, View view,
        int position) {
        // TODO ...
    }
});

CommonAdapter、CommonRecyclerAdapter区别

CommonAdapter适用于:ListView/GridView
CommonRecyclerAdapter适用于:RecyclerView
使用方式都一样

BaseAdapterHelper 使用示例

helper.setText(R.id.viewId, text)
      .setTag(R.id.viewId, objectTag)
      .setAlpha(R.id.viewId, 0.6f)
      .setBackgroundColor(R.id.viewId, R.color.colorResId)
      .setBackgroundRes(R.id.viewId, R.drawable.drawableResId)
      .setChecked(R.id.viewId, true)
      .setImageBitmap(R.id.viewId,bitmap)
      .setImageDrawable(R.id.viewId,drawable)
      .setImageResource(R.id.viewId, R.drawable.drawableResId)
      .setImageUrl(R.id.viewId, url)
      .setProgress(R.id.viewId,progress)
      .setProgress(R.id.viewId,progress,max)
      .setRating(R.id.viewId, rating)
      .setRating(R.id.viewId, rating, max)
      .setTextColor(R.id.viewId, R.color.colorResId)
      .setTextColorRes(R.id.viewId, R.color.colorResId)
      .setTextColorRes(R.id.viewId, R.color.colorResId, theme) //New in version 1.2
      //TextView添加超链接,更多属性参考:android.text.util.Linkify#addLinks(TextView text, int mask)
      .addLinks(R.id.viewId, , Linkify.ALL) //New in version 1.2
      //单个TextView设置Typeface
      .setTypeface(R.id.viewId, typeface)
      //多个TextView设置Typeface
      .setTypeface(typeface, R.id.xxx1, R.id.xxx2,R.id.xxx3, ...)
      .setVisible(R.id.viewId, View.VISIBLE)
      //ProgressBar设置Max
      .setMax(R.id.viewId, max)
      //ListView设置adapter
      .setAdapter(R.id.viewId, adapter)
      //下面为View常用点击事件设置
      .setOnTouchListener(R.id.viewId, View.OnTouchListener)
      .setOnClickListener(R.id.viewId, View.OnClickListener)
      .setOnLongClickListener(R.id.viewId, View.OnLongClickListener)
      .setOnItemClickListener(R.id.viewId, AdapterView.OnItemClickListener)
      .setOnItemLongClickListener(R.id.viewId, AdapterView.OnItemLongClickListener)
      .setOnItemSelectedClickListener(R.id.viewId, AdapterView.OnItemSelectedListener);

//获取item的convertView
View convertView = helper.getView();

//如果上面的属性不够用,可以通过getView(viewId)拿到View,然后进行属性设置
View childView = helper.getView(R.id.viewId);

自定义图片加载

public class YourXXX implements ImageLoad {

    @Override public void load(Context context, ImageView imageView, String imageUrl) {

        //使用Glide加载图片
        Glide.with(context).load(imageUrl).into(imageView);

        or

        //使用Picasso加载图片
        Picasso.with(context).load(url).into(imageView);

        or

        fresco
        Android-Universal-Image-Loader
        自定义
        ...
    }
}

注意事项

//加载网络图片之前,请调用setImageLoad方法,设置网络图片加载的实现类
helper.setImageLoad(new GlideImageLoad());
helper.setImageUrl(R.id.xxx,url);

常用的数据操作

//CommonAdapter、CommonRecyclerAdapter都实现了IData接口,里面包含了一些常用的数据操作

void add(T elem);

void addAll(List<T> elem);

void set(T oldElem, T newElem);

void set(int index, T elem);

void remove(T elem);

void remove(int index);

void replaceAll(List<T> elem);

boolean contains(T elem);

void clear();
通过封装BaseAdapter和RecyclerView.Adapter得到的通用的,简易的Adapter。项目地址:https://github.com/tianzhijiexian/CommonAdapter 效果图:已解决的问题 提升item的独立性,完美支持item被多处复用 item会根据type来做自动复用 支持多种类型的item 一个item仅会调用一次setViews(),避免重复建立监听器 一个item仅会触发一次绑定视图的操作,提示效率 支持dataBinding和其他第三方注入框架 提供了getView()方法来简化findViewById 支持通过item的构造方法来传入Activity对象 支持通过item的构造方法来传入item中事件的回调 提供了getConvertedData(data, type)方法来对item传入的数据做转换,方便拆包和提升item的复用性 支持viewpager的正常加载模式和懒加载 支持快速将listview的适配器切换为recyclerView的适配器 viewpager的notifyDataSetChanged可以正常更新界面 支持recyclerView的添加头部和底部 支持适配器的数据自动绑定,只用操作数据便可,adapter会自动notify界面零、重要接口adapter的item必须实现此接口,接口源码如下:public interface AdapterItem<T> {     /**      * @return item布局文件的layoutId      */     @LayoutRes     int getLayoutResId();     /**      * 初始化views      */     void bindViews(final View root);     /**      * 设置view的参数      */     void setViews();     /**      * 根据数据来设置item的内部views      *      * @param model    数据list内部的model      * @param position 当前adapter调用item的位置      */     void handleData(T model, int position); }例子:public class TextItem implements AdapterItem<DemoModel> {     @Override     public int getLayoutResId() {         return R.layout.demo_item_text;     }     TextView textView;     @Override     public void bindViews(View root) {         textView = (TextView) root.findViewById(R.id.textView);     }     @Override     public void setViews() { }     @Override     public void handleData(DemoModel model, int position) {         textView.setText(model.content);     } }一、ListView GridView的通用适配器——CommonAdapter只需继承CommonAdapter便可实现适配器:listView.setAdapter(new CommonAdapter<DemoModel>(data, 1) {     public AdapterItem<DemoModel> createItem(Object type) {         return new TextItem();     } });二、RecyclerView的通用适配器——CommonRcvAdapter通过继承CommonRcvAdapter来实现适配器:mAdapter = new CommonRcvAdapter<DemoModel>(data) {  public AdapterItem createItem(Object type) {         return new TextItem();   } };三、ViewPager的通用适配器——CommonPagerAdapter通过继承CommonPagerAdapter来实现适配器:viewPager.setAdapter(new CommonPagerAdapter<DemoModel>() {     public AdapterItem createItem(Object type) {         return new TextItem();     } });设计思路1. Adapter如果用adapter常规写法,你会发现代码量很大,可读性低。如果adapter中有多个类型的Item,我们还得在getView()中写很多if-else语句,很乱。 而现在我让adapter的代码量减少到一个8行的内部类,如果你需要更换item只需要动一行代码,真正实现了可插拔化。最关键的是item现在作为了一个独立的对象,可以方便的进行复用。2. AdapterItem和原来方式最为不同的一点就是我把adapter的item作为了一个实体,这种方式借鉴了RecyclerView中ViewHolder的设计。把item作为实体的好处有很多,比如复用啊,封装啊,其余的就不细说了。3. 分层在使用过程中,我发现如果adapter放在view层,那就会影响到view层的独立性。此外adapter中经常有很多数据处理的操作,比如通过type选择item,数据的拆包、转换等操作。于是我还是推荐把adapter放在mvp的p层,或者是mvvm的m层。通过在实际的项目中使用来看,放在m或p层的效果较好,view的复用也比较好做。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值