zoukankan      html  css  js  c++  java
  • Android适配器之DataModifyHelper数据操作类的封装

    编写适配器代码时常常被以下几个问题所困扰:
    1.业务层和适配器中对同一组数据进行维护,难以管理
    2.在业务层针对数据进行修改后必须通知适配器更新,否则提示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对象,其对应于列表控件中显示的数据。
    setNotifyAdapterDataSetChange为外界提供数据更新的接口注入方法,在数据修改后调用INotifyDataSetChange的notify...()方法即可通知适配器更新。

    开发人员可自行扩展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();
    }
    }
    setDataResource方法中,针对List数据先进行非空过滤,再判断List非空后进行数据修改,以确保mDataResources集合始终非空。这里会注意到其参数使用无限制通配符,主要是为了提高程序的扩展性,当适配器基于接口编程时能方便set数据。(使用transform的原因List<Child>无法转为List<Parent>)
    addDataResource的实现过程同setDataResource基本一致,都是针对数据集进行非空过滤以及判断等一系列处理。


    使用示例(博客园可通过左边"搜索"进入):






  • 相关阅读:
    .netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求
    .netcore持续集成测试篇之搭建内存服务器进行集成测试一
    .netcore持续集成测试篇之Xunit数据驱动测试
    .netcore持续集成测试篇之开篇简介及Xunit基本使用
    .net持续集成测试篇之Nunit 测试配置
    .net持续集成测试篇之Nunit参数化测试
    .net持续集成测试篇之Nunit that断言
    .net持续集成测试篇之Nunit文件断言、字符串断言及集合断言
    .net持续集成测试篇之Nunit常见断言
    .net持续集成单元测试篇之单元测试简介以及在visual studio中配置Nunit使用环境
  • 原文地址:https://www.cnblogs.com/linux007/p/5809433.html
Copyright © 2011-2022 走看看