一种简单的 Adapter 解决方案,支持多种 ViewType,轻松创建 ViewHolder
模式 Adapter. 支持 ListView
和 RecyclerView
.
仅支持 ListView
dependencies {
compile 'com.github.mzule.easyadapter:easyadapter:1.1.3'
}
需要支持 RecyclerView
dependencies {
compile 'com.github.mzule.easyadapter:easyadapter:1.1.3'
compile 'com.github.mzule.easyadapter:easyadapterrecycler:1.1.3'
}
项目包含四个类, ViewType
, SingleTypeAdapter
, MultiTypeAdapter
, TypePerEntityAdapter
, 其中 ViewType
负责创建、绑定( Hold )、渲染View; SingleTypeAdapter
支持单独一种样式类型的Adapter, MultiTypeAdapter
, TypePerEntityAdapter
支持多种样式类型的Adapter;TypePerEntityAdapter
是 MultiTypeAdapter
的子类。
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)
方法,可以根据声明的类型进行强制转换。
onCreate
可以通过调用setContentView(int)
或者setContentView(View)
创建 View,初始化成员变量;onRender(int, T)
负责渲染UI,绑定数据.
ViewType
还提供了一个 getAdapter()
方法直接直接操作 Adapter.以及一个 isEditMode()
检查当前是否在编辑模式.
项目为 ListView
, RecyclerVIew
个提供了 3 个 Adapter
基类,名字一样,只是包名略作区分,分别是 com.github.mzule.easyadapter
, com.github.mzule.easyadapter.recycler
。下面一一说明。
SingleTypeAdapter
适合仅有一种类型View的 ListView
,典型实现如下:
class PlainAdapter extends SingleTypeAdapter<String> {
public PlainAdapter(Context context) {
super(context);
}
@Override
protected Class<? extends ViewType> singleViewType() {
return TipViewType.class;
}
}
顾名思义,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;
}
}
TypePerEntityAdapter
是 MultiTypeAdapter
的子类,适用于每个数据实体 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);
}
}
通过 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);