1.业务层和适配器中对同一组数据进行维护,难以管理
The content of the adapter has changed but ListView did not receive anotification
3.业务层修改数据时充斥大量的非空&数据标准化等冗余代码
针对前两个问题,可以将数据交由适配器去管理,业务层对数据的增删改查均通过适配器进行处理,这样仅需要维护好adapter中的数据即可。
关于数据的非空判断以及增删改查等操作,可以抽取数据操作类来简化适配器当中的逻辑。
下面给出具体的代码实现
适配器更新方式接口定义,其具体实现可根据适配器类型(BaseAdapter/PageAdapter/RecyclerView.Adapter)自行调整。
/**
* @Description:
* @author: Xiaoxuan948
* @date: 2016/7/20 20:39
*/
public interface INotifyAdapterDataSetChange {
/**
* 通知适配器更新
*/
void notifyUnityAdapterDataChange();
void notifyUnityAdapterDataInsert(int position);
void notifyUnityAdapterDataUpdate(int position);
void notifyUnityAdapterDataRemove(int position);
}
接口IAdapterDataModifyHelper定义针对数据的各种操作,其子类AbsDataModifyHelper进行简要实现。
public abstract class AbsDataModifyHelper<T> implements IAdapterDataModifyHelper<T> {
private final UtilsLog lg = UtilsLog.getLogger(AbsDataModifyHelper.class);
protected List<T> mDataResources;
protected INotifyAdapterDataSetChange INotifyDataSetChange;
public AbsDataModifyHelper() {
this.mDataResources = new ArrayList<>();
}
@Override
public final void setNotifyAdapterDataSetChange(INotifyAdapterDataSetChange INotifyDataSetChange) {
this.INotifyDataSetChange = INotifyDataSetChange;
}
@Override
public final List<T> getDataResources() {
return mDataResources;
}
//省略部分代码
}
观察可知,在 AbsDataModifyHelper 构造方法中实例化 mDataResources对象,其对应于列表控件中显示的数据。
开发人员可自行扩展AbsDataModifyHelper,下面给出一个示例实现类DataModifyHelper。
/**
* @Description:
* @author: Xiaoxuan948
* @date: 2016/8/26 10:04
*/
public class DataModifyHelper<T> extends AbsDataModifyHelper<T> {
private final UtilsLog lg = UtilsLog.getLogger(DataModifyHelper.class);
@Override
public void setDataResource(List<? extends T> setDataResources) {
/*针对集合空数据进行处理*/
if (UtilsCollections.isCollectionNotEmpty(setDataResources) && setDataResources.contains(null)) {
lg.e("setDataResource集合包含null数据");
setDataResources = Lists.newArrayList(Collections2.filter(setDataResources, new Predicate<T>() {
@Override
public boolean apply(T input) {
return input != null;
}
}));
}
if (!UtilsCollections.isCollectionNotEmpty(setDataResources)) {
return;
}
/*针对类型不匹配进行处理*/
this.mDataResources = Lists.transform(setDataResources, new Function<Object, T>() {
@Override
public T apply(Object input) {
return (T) input;
}
});
INotifyDataSetChange.notifyUnityAdapterDataChange();
}
@Override
public void addDataResource(int location, List<? extends T> addDataResources) {
if (UtilsCollections.isCollectionNotEmpty(addDataResources) && addDataResources.contains(null)) {
lg.e("addDataResource集合包含null数据");
addDataResources = Lists.newArrayList(Collections2.filter(addDataResources, new Predicate<T>() {
@Override
public boolean apply(T input) {
return input != null;
}
}));
}
if (!UtilsCollections.isCollectionNotEmpty(addDataResources)) {
lg.e("addDataResource:待加入的集合为空");
return;
}
location = proofOperateDataLocation(location);
this.mDataResources.addAll(location, addDataResources);
INotifyDataSetChange.notifyUnityAdapterDataInsert(location);
}
@Override
public void reviseDataResource(int position, T enity) {
if (isOperateLocationRight(position)) {
this.mDataResources.set(position, enity);
INotifyDataSetChange.notifyUnityAdapterDataUpdate(position);
} else {
lg.e("reviseDataResource failed because position out of size " + this.mDataResources.size());
}
}
@Override
public void removeDataResourceOnPosition(int position) {
this.mDataResources.remove(position);
INotifyDataSetChange.notifyUnityAdapterDataRemove(position);
}
@Override
public void clear() {
this.mDataResources.clear();
INotifyDataSetChange.notifyUnityAdapterDataChange();
}
}
mDataResources集合始终非空。这里会注意到其参数使用无限制通配符,主要是为了提高程序的扩展性,当适配器基于接口编程时能方便set数据。(使用 transform的原因 : List<Child> 无法转为 List<Parent>)
addDataResource的实现过程同setDataResource基本一致,都是针对数据集进行非空过滤以及判断等一系列处理。
使用示例(博客园可通过左边"搜索"进入):
Android适配器之基于BaseAdapter定义AbslistView万能适配器
Android适配器之 V7扩展包 RecyclerView 的使用以及万能适配器的封装实现
Android适配器之定义PagerAdapter万能适配器