基于抽象布局和炒鸡牛鼻adapter写的base下拉刷新功能,只需要一点点代码,就实现了不同数据的下拉刷新

楼主5月份就已经来北京这边找工作了,本来以为堂堂天朝的帝都开发水平秒杀我们这些偏远地区的渣渣,但是在这边工作了几个月发现那其实只是少数情况,
不管作为一个什么样的app,下拉刷新的功能基本都是比不可少的,但是换了两家公司发现,一个非常牛逼的公司开发的app竟然都没有人封装这个功能,
作为一个程序猿你这么写代码真是越来越退化了, 不瞎扯了,上正题

本文只是为了封装下拉刷新功能,所以没有讲究现在到底用哪种下拉刷新控件比较好,我选的是以前项目中使用的XListView ,  

为了方便 在每一个activity或者fragment 中控制页数,我在XListView 中添加了几个方法

public  static final int FIRST_PAGE=1;开始也的页数标签,可能是第1页,也可能是0页

public int  nextPage(){
   page++;
   return page;
}

public void resetPage(){
   page=FIRST_PAGE;
}

public int currentPage(){
   return page;
}

public void privoidsPage(){
   if(page==FIRST_PAGE)
      return;
   page--;
}
 

这样的话在使用的时候直接调用 xlv.nextPage() 就可以方便的下一页了,省时省力还省心...

为了更好的约束下拉刷新时具体涉及到哪些方法,我定义了一个接口类,需要实现的功能尽收眼底

因为每次加载的数据不一定,所以这里面我用了泛型 

public interface RefreshLoader<T> {
    加载完成  是否成功  如果成功则页数不会退
    // 如果失败则页数回退   如果当前页数为0  则页数回退为0
    void onLoadFinish(boolean success,List<T> list);
    上拉更新
    void onLoadNextPage();
    ///下拉刷新
    void onLoadFirstPage();
    通过sp 读取数据
    List<T>  readList();
    清除sp中的该类型列表
    void clearList();
    保存sp中该类型列表
    void saveList(List<T> list);
    ///每一页缓存数据的个数
    int pageCount();
}


下面就是主要的代码了,基本没有什么逻辑,

public abstract class BaseCacheActivity<T> extends AppCompatActivity implements RefreshLoader<T> {

    public static final int TOP_MODEL = 1;
    public static final int BOTTOM_MDOEL = 2;

    public static final int BOTH = TOP_MODEL | BOTTOM_MDOEL;


    private XListView lv_list;
    private TsmBaseAdapter<T> adapter;
    protected int model;
    private CustomProgressDialog loadingdialog;
    private EmptyView empty_view;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        ActionBar bar = this.getSupportActionBar();
        bar.hide();
        lv_list = (XListView) findViewById(R.id.lv_test);
        ViewStub vs_empty = (ViewStub) findViewById(R.id.vs_empty);
        vs_empty.inflate();
        View view = findViewById(R.id.inflate_id);
        lv_list.setEmptyView(view);
        empty_view = (EmptyView) view.findViewById(R.id.empty_view);
        empty_view.setEmptyBtnClickListeners(new EmptyView.EmptyBtnClickListeners() {
            @Override
            public void onClick() {
                showLoadingDialog();
                lv_list.resetPage();
                onLoadDate(lv_list.currentPage(), pageCount());
            }
        });
    }

    /**
     * 初始化下拉刷新 由子类调用,
     *
     * @param model
     * @param adapter
     */
    public void initLoader(int model, final TsmBaseAdapter<T> adapter) {
        this.model = model;
        this.adapter = adapter;
        lv_list.setPullRefreshEnable(isTopCanRefresh());
        lv_list.setPullLoadEnable(isBottemRefresh());
        lv_list.setAdapter(adapter);
        lv_list.setXListViewListener(new XListView.IXListViewListener() {
            @Override
            public void onRefresh() {
                showLoadingDialog();
                onLoadFirstPage();
            }

            @Override
            public void onLoadMore() {
                showLoadingDialog();
                onLoadNextPage();
            }
        });
        initDate();
    }

    /**
     * 初始数据,为空显示加载dialog并加载
     * 不为空静默加载
     */
    private void initDate() {
        List<T> list = this.readList();
        if (list == null || list.size() == 0) {
            showLoadingDialog();///显示加载框
        }
        this.adapter.setList(list);
        lv_list.resetPage();
        this.onLoadDate(lv_list.currentPage(), pageCount());
    }

    /**
     * 显示加载进度框
     */
    private void showLoadingDialog() {
        if (loadingdialog == null)
            loadingdialog = CustomProgressDialog.createDialog(this, true);
        if (!loadingdialog.isShowing())
            loadingdialog.show();
    }

    /**
     * 隐藏加载进度框
     */
    private void hideLoadingDialog() {
        if (loadingdialog == null)
            return;
        if (loadingdialog.isShowing())
            loadingdialog.dismiss();
    }

    /**
     * 是否可以下拉刷新
     *
     * @return
     */
    public boolean isTopCanRefresh() {
        return (this.model & TOP_MODEL) > 0;
    }

    /**
     * 是否可以下拉加载
     *
     * @return
     */
    public boolean isBottemRefresh() {
        return (this.model & BOTTOM_MDOEL) > 0;
    }

    /**
     * 加载数据方法 抽象方法
     * 子类必须自己实现, 通过不同的接口返回不同类型的数据
     * @param page
     * @param pageCount
     */
    public abstract void onLoadDate(int page, int pageCount);


    /**
     * 刷新完成
     *
     * @param success 是否成功
     * @param list    返回的列表
     */
    @Override
    public void onLoadFinish(boolean success, List<T> list) {
        lv_list.stopRefresh();
        lv_list.stopLoadMore();
        hideLoadingDialog();
        if (lv_list.currentPage() == XListView.FIRST_PAGE) {
            /**
             * 只有在加载失败并且没有网的情况下
             * 设置emptyview 为 没有网装填
             * 其他设置为空数据状态
             * */
            if (!success && !Utils.hasNetWork()) {
                empty_view.setImage(R.mipmap.meiwang);
            } else{
                empty_view.setImage(R.mipmap.meishuju);
            }
            adapter.setList(list);
        } else {
            adapter.addList(list);
        }
        if (!success)
            lv_list.privoidsPage();
    }

    /**
     * 上啦更新
     */
    @Override
    public void onLoadNextPage() {
        lv_list.nextPage();
        onLoadDate(lv_list.currentPage(), pageCount());
    }

    /**
     * 下拉刷新
     */
    @Override
    public void onLoadFirstPage() {
        lv_list.resetPage();
        onLoadDate(lv_list.currentPage(), pageCount());
    }

    /**
     * 从sp中获取数据
     * 静默刷新
     *
     * @return
     */
    @Override
    public List<T> readList() {
        Class<?> cls = this.getModelClass();
        if (cls == null)
            return null;
        String json = AppConfig.getInstance(this).getString(this, cls.getSimpleName());
        if (Utils.isEmpty(json))
            return null;
        List<T> list = (List<T>) GsonUtil.getList(json, cls);
        return list;
    }

    /**
     * 获取缓存的数据类型
     *
     * @return
     */
    public Class<?> getModelClass() {
        return null;
    }

    /**
     * 清除sp的该列表的数据
     */
    @Override
    public void clearList() {
        Class<?> cls = getModelClass();
        if (cls == null)
            return;
        AppConfig.getInstance(this).putString(this, cls.getSimpleName(), "");
    }

    /**
     * 将列表保存到sp中
     * 只保存下路刷新时候的数据
     *
     * @param list
     */
    @Override
    public void saveList(List<T> list) {
        Class<?> cls = getModelClass();
        if (cls == null) {
            return;
        }
        if (list == null) {
            AppConfig.getInstance(this).putString(this, cls.getSimpleName(), "");
            return;
        }
        String json = GsonUtil.G.toJson(list);
        AppConfig.getInstance(this).putString(this, cls.getSimpleName(), json);
    }

    /**
     * 页面结束保存数据
     */
    @Override
    protected void onDestroy() {
        saveList(adapter.getList());
        super.onDestroy();
    }

    /**
     * 每页缓存的数据
     *
     * @return
     */
    @Override
    public int pageCount() {
        return 10;
    }
}


最后是mainactivity的代码  哈哈  是不是很简洁

public class MainActivity extends BaseCacheActivity<EmptyBean> {


    private MyAdapter adapter;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        adapter=new MyAdapter(this,null);
        handler=new Handler();
        initLoader(BaseCacheActivity.BOTH,adapter);
    }

    @Override
    public void onLoadDate(int page, int pageCount) {
        Log.i("info","---------------onLoadDate--------------page:"+page);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                int a = new Random().nextInt(10);
              onLoadFinish(a>5,a>5?newshuju():null);
            }
        },2000);
    }
    
/**
 * 获取缓存的数据类型
 *如果不重写该方法,则本地不会保存数据
 * @return
 */
public Class<?> getModelClass() {
    return null;
}

/**
 * 清除sp的该列表的数据
 */
@Override
public void clearList() {
    Class<?> cls = getModelClass();
    if (cls == null)
        return;
    AppConfig.getInstance(this).putString(this, cls.getSimpleName(), "");
}

/**
 * 将列表保存到sp中
 * 只保存下路刷新时候的数据
 *
 * @param list
 */
@Override
public void saveList(List<T> list) {
    Class<?> cls = getModelClass();
    if (cls == null) {
        return;
    }
    if (list == null) {
        AppConfig.getInstance(this).putString(this, cls.getSimpleName(), "");
        return;
    }
    String json = GsonUtil.G.toJson(list);
    AppConfig.getInstance(this).putString(this, cls.getSimpleName(), json);
}

/**
 * 页面结束保存数据
 */
@Override
protected void onDestroy() {
    saveList(adapter.getList());
    super.onDestroy();
}

/**
 * 每页缓存的数据
 *
 * @return
 */
@Override
public int pageCount() {
    return 10;
}


由于获取网络状态和加载数据是否成功我都使用的随机数判断的返回状态,所以在下拉刷新或者上拉更新的过程所有可能都会交替出现,

千万不要认为楼主写的代码有bug   (-->_<--)!!!  




最后附上demo源码    http://download.csdn.net/detail/qq_22256027/9665492

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值