Easyadapter

Easy to use adapters.

This project is maintained by mzule

EasyAdapter

一种简单的Adapter解决方案,支持多种ViewType,轻松创建ViewHolder模式Adapter. 支持ListViewRecyclerView.

安装

仅支持ListView

dependencies {
    compile 'com.github.mzule.easyadapter:easyadapter:1.1.2'
}

需要支持RecyclerView

dependencies {
    compile 'com.github.mzule.easyadapter:easyadapter:1.1.2'
    compile 'com.github.mzule.easyadapter:easyadapterrecycler:1.1.2'
}

使用步骤

项目包含四个类, ViewType, SingleTypeAdapter, MultiTypeAdapter, TypePerEntityAdapter, 其中ViewType负责创建、绑定(Hold)、渲染View;SingleTypeAdapter支持单独一种样式类型的Adapter, MultiTypeAdapter, TypePerEntityAdapter支持多种样式类型的Adapter;TypePerEntityAdapterMultiTypeAdapter的子类。

1. 编写ViewType(s)

ViewType负责创建、绑定、渲染View,每个ViewType对应传统模式下的一个ViewHolder,一个典型的ViewType实现如下:

public class TipViewType extends ViewType<String> {
    private TextView tipView;

    @Override
    public void onCreate() {
        setContentView(R.layout.item_tip);
        this.tipView = findViewById(R.id.tip);
    }

    @Override
    public void onRender(int position, String tip) {
        tipView.setText(tip);
    }
}

ViewType提供了一个findViewById(int)方法,可以根据声明的类型进行强制转换。

  1. onCreate可以通过调用setContentView(int)或者setContentView(View)创建View,初始化成员变量;
  2. onRender(int, T)负责渲染UI,绑定数据.

ViewType还提供了一个getAdapter()方法直接直接操作Adapter.以及一个isEditMode()检查当前是否在编辑模式.

2. 选择合适的Adapter

项目为ListView,RecyclerVIew个提供了3个Adapter基类,名字一样,只是包名略作区分,分别是com.github.mzule.easyadapter,com.github.mzule.easyadapter.recycler。下面一一说明。

1. SingleTypeAdapter

SingleTypeAdapter适合仅有一种类型View的ListView,典型实现如下:

class PlainAdapter extends SingleTypeAdapter<String> {

    public PlainAdapter(Context context) {
        super(context);
    }

    @Override
    protected Class<? extends ViewType> singleViewType() {
        return TipViewType.class;
    }
}

2. MultiTypeAdapter

顾名思义,MultiTypeAdapter适用于需要在ListView上显示多种类型View的时候,比如说微博客户端,一堆微博之间,夹杂几个广告,正好适用。典型实现:

class ArticleAdapter extends MultiTypeAdapter<Article> {

    public ArticleAdapter(Context context) {
        super(context);
    }

    @Override
    protected void registerViewTypes() {
        registerViewType(ArticleBriefViewType.class);
        registerViewType(ArticleFullViewType.class);
    }

    @Override
    protected Class<? extends ViewType> getViewType(int position, Article data) {
        switch (data.getStyle()) {
            case Article.STYLE_FULL:
                return ArticleFullViewType.class;
            case Article.STYLE_BRIEF:
                return ArticleBriefViewType.class;
        }
        return null;
    }
}

3.TypePerEntityAdapter

TypePerEntityAdapterMultiTypeAdapter的子类,适用于每个数据实体class都对应不同的ViewType实现,例如:

class TimelineAdapter extends TypePerEntityAdapter<Object> {

    public TimelineAdapter(Context context) {
        super(context);
    }

    @Override
    protected void mapEntityViewTypes() {
        mapEntityViewType(Post.class, PostViewType.class);
        mapEntityViewType(Repost.class, RepostViewType.class);
        mapEntityViewType(String.class, TipViewType.class);
        mapEntityViewType(Recommend.class, RecommendViewType.class);
        mapEntityViewType(Ad.class, AdViewType.class);
    }
}

3. 应用Adapter

通过ListView#setAdapter(Adapter)使用Adapter,通过add(List)/addAndNotify(List)/clear()/clearAndNotify()添加或修改Adapter内的数据。add(List)addAndNotify(List)的区别在于是否自动调用notifyDataSetChanged(), clear亦然。

ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(adapter);
List<String> fake = new ArrayList<>();
for (int i = 0; i < 100; i++) {
    fake.add(UUID.randomUUID().toString());
}
adapter.addAndNotify(fake);

尽情享用