Android应用开发中,经常需要使用到界面的下拉刷新和上拉加载,在support v7之前,一般都是用ListView去做列表视图,而ListView对EmptyView是提供支持的,并且有许多开源库拓展了ListView使其支持了下拉刷新和上拉加载,但是许多这种拓展都会在ListView现实EmptyView时失效,原因就是ListView实际上已经被Gone了。

  在support v7之后,google提供了一个神器,RecyclerView,相信大部分人都已经不陌生了,RecyclerView提供了更强大的Recycler机制,能够完美实现ListView的基础上,使开发者的代码更简洁,效率更高,并且能实现各种不同的布局。但是凡事都有个但是,RecyclerView目前为止并没有提供Header,Footer,EmptyView的内部支持,所以大部分的开发者的方案是使用其他拓展RecyclerView或者Layout来实现,google提供的SwipeLayout可以实现下拉刷新的功能,但是如果要实现上拉加载或者更改header都是比较麻烦的。

  但是现在有许多的开源方案可以实现,比如SwipeToLoadLayout,虽然这个开源项目的star并不多,但是它是我发现的最方便实现下拉刷新和上拉加载的开源库了。建议大家也可以使用试试。

  美中不足的是,SwipeToLoadLayout并没有提供EmptyView的内部支持,相信大部分的这类开源库都没有支持吧。但是没关系,我们可以自己去实现它,并且附带实现自动开启关闭LoadMore的功能(在Empty时就应该自动关闭Loadmore)注:希望你在阅读下面的代码之前先已经研究并使用过SwipeToLoadLayout了

  1、首先我们需要添加一个EmptyView在swipe_target里面

 <?xml version="1.0" encoding="utf-8"?>
<com.duoniu.benfu.widget.layout.SwipeToLoadLayoutEmptySupport
android:id="@+id/swipeToLoadLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
app:swipe_style="classic"> <include
android:id="@+id/swipe_refresh_header"
layout="@layout/layout_logo_header"/> <RelativeLayout
android:id="@id/swipe_target"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <com.duoniu.benfu.widget.recyclerview.RecyclerViewEmptySupport
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"> </com.duoniu.benfu.widget.recyclerview.RecyclerViewEmptySupport> <include layout="@layout/empty_or_error"
android:id="@+id/emptyView"
android:visibility="gone"/>
</RelativeLayout> <include
android:id="@+id/swipe_load_more_footer"
layout="@layout/layout_classic_footer"/> </com.duoniu.benfu.widget.layout.SwipeToLoadLayoutEmptySupport>

  可以看到,我们的swipe_target不在只是单独的一个RecyclerView了,而且一个RelativeLayout,里面放了一个RecyclerView和一个EmptyView.当然,这个EmptyView你可以任意实现,默认visibility是gone了。

  2、拓展RecyclerView

  为了使RecycleView能够支持EmptyView,我们需要监听到RecyclerView的item数量变换来控制EmptyView的现实

 public class RecyclerViewEmptySupport extends RecyclerView {

     private View emptyView;

     private WeakReference<SwipeToLoadLayout> weakSwipeToLoadLayout;

     private AdapterDataObserver emptyObserver = new AdapterDataObserver() {
@Override
public void onChanged() {
Adapter<?> adapter = getAdapter();
if (adapter != null && emptyView != null){
if (adapter.getItemCount() == 0){
emptyView.setVisibility(View.VISIBLE);
}
else{
emptyView.setVisibility(View.GONE);
}
if (weakSwipeToLoadLayout != null && weakSwipeToLoadLayout.get() != null){
weakSwipeToLoadLayout.get().setLoadMoreEnabled(adapter.getItemCount() > 0);
}
}
}
}; public RecyclerViewEmptySupport(Context context) {
super(context);
} public RecyclerViewEmptySupport(Context context, AttributeSet attrs) {
super(context, attrs);
} public RecyclerViewEmptySupport(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
if (adapter != null){
adapter.registerAdapterDataObserver(emptyObserver);
}
emptyObserver.onChanged();
} public void setEmptyView(View emptyView) {
this.emptyView = emptyView;
} public void setSwipeToLoadLayout(SwipeToLoadLayout swipeToLoadLayout) {
this.weakSwipeToLoadLayout = new WeakReference<>(swipeToLoadLayout);
} }

  我们使用了sdk中的AdapterDataObserver来监听数据变化,在onChange中实现如果item已经为0了就现实emptyView,反之不显示,另外,如果item已经为0了就禁用SwipeToLoadLayout的加载更多功能。

  3、拓展SwipeToLoadLayout

  细心的朋友会发现RecyclerViewEmptySupport的emptyView字段是从外部set的,很明显,RecyclerView是没法知道它边上有个兄弟View的,所以需要父布局去set

 public class SwipeToLoadLayoutEmptySupport extends SwipeToLoadLayout {

     public SwipeToLoadLayoutEmptySupport(Context context) {
super(context);
} public SwipeToLoadLayoutEmptySupport(Context context, AttributeSet attrs) {
super(context, attrs);
} public SwipeToLoadLayoutEmptySupport(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
} @Override
protected void onFinishInflate() {
super.onFinishInflate();
View targetView = this.findViewById(R.id.swipe_target);
if (targetView != null) {
View emptyView = targetView.findViewById(R.id.emptyView);
View recyclerView = targetView.findViewById(R.id.recyclerView);
if (recyclerView instanceof RecyclerViewEmptySupport){
RecyclerViewEmptySupport recyclerViewEmptySupport = ((RecyclerViewEmptySupport) recyclerView);
recyclerViewEmptySupport.setSwipeToLoadLayout(this);
if (emptyView != null && recyclerView != null) {
recyclerViewEmptySupport.setEmptyView(emptyView);
}
} } }
}

  4、使用SwipeToLoadLayoutEmptySupport

  其实到此为止,我们已经拓展完成了,接下来就是使用了,使用上并没有什么技巧,就只是在所有需要上拉加载,下拉刷新以及空视图的地方include一下我们刚开始写的布局即可(是不是感觉很方便?)

  

  

拓展开源库SwipeToLoadLayout实现EmptyView和Empty时自动禁用LoadMore的更多相关文章

  1. 各种有用的PHP开源库精心收集

    转自:http://my.oschina.net/caroltc/blog/324024 摘要 各种有用的PHP开源库精心收集,包含图片处理,pdf生成,网络协议,网络请求,全文索引,高性能搜索,爬虫 ...

  2. 在别的地方看的<<给程序员介绍一些C++开源库>>,记录给大家共同学习

    首先说明这篇文章不是出自我手,大家共同学习. 引用地址:http://oss.org.cn/?action-viewnews-itemid-61998. C++开源库,欢迎补充. C++在“商业应用” ...

  3. [转贴]C++开源库

    C++在“商业应用”方面,曾经是天下第一的开发语言,但这一 桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C# ...

  4. 33 个 2017 年必须了解的 iOS 开源库

    本文翻译自Medium,原作者为Pawe? Bia?ecki 照片版权:(Unsplash/Markus Pe) 你好,iOS 开发者们!我的名字叫 Pawe?,我是一个独立 iOS 开发者,并且是  ...

  5. C++开源库,欢迎补充。

    转载自:http://blog.csdn.net/kobejayandy/article/details/8681741 C++在"商业应用"方面,曾经是天下第一的开发语言,但这一 ...

  6. 33 个 2017 年必须了解的 iOS/swift 开源库第三方库

    本文翻译自Medium,原作者为 Paweł Białecki&lt;img src="https://pic3.zhimg.com/v2-c786777447261347b0d97 ...

  7. ios很好的开源库

    Tim9Liu9/TimLiu-iOS 自己总结的iOS.mac开源项目及库,持续更新.. 目录 UI 下拉刷新 模糊效果 AutoLayout 富文本 图表 表相关与Tabbar 隐藏与显示 HUD ...

  8. Android 使用开源库载入网络图片

    Android 使用开源库载入网络图片,使用开源库载入图片.单击listview弹出popupwindow弹出框详情查看: Android 单击listview弹出popupwindow弹出框 ,里面 ...

  9. C++开源库,欢迎补充

    C++在“商业应用”方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C#语 ...

随机推荐

  1. YouTube上的版权保护

    早在2007年的时候,我曾写过一篇名为“YouTube: The Big Copyright Lie”(YouTube:关于版权的弥天大谎)的文章,表达了我对YouTube又爱又恨的情感纠结: 现在回 ...

  2. 搭建一个全栈式的HTML5移动应用框架(纯干货,亲!)

    打开HTML5的技术网站,满屏的“5个推荐的JavaScript框架”.“10个移动应用框架”,全都是你妹的框架, 但是,你知道这些框架是干毛用的吗?来吧,我们来梳理一下吧 目前HTML5涉及的框架大 ...

  3. 编辑器TP

    http://www.itshipin.com/blog/archives/category/php/thinkphp

  4. TP复习14

    ## ThinkPHP 3.1.2 控制器的模块和操作#讲师:赵桐正微博:http://weibo.com/zhaotongzheng 本节课大纲:一.空模块和空操作 1.空操作 function _ ...

  5. Ubantu下FTP服务器资源进行控制

    在FTP服务器的管理中无论对本地用户还是匿名用户,对于FTP服务器资源的使用都需要进行控控制, 避免由于负担过大造成FTP服务器运行异常, 可以添加以下配置项对FTP客户机使用FTP服务器资源进行控制 ...

  6. mysql主从复制 主从配置(windows系统上)

    OS:Windows7 DB:MYSQL5.6.2 1.正常安装第一个mysql(安装步骤省略)  2.在控制面板里停止第一个mysql服务  3.将C:\Program Files\MySQL目录下 ...

  7. 使用docker-hub

    使用docker hub 需要其账号 基本操作 查找镜像 sudo docker search centos 每个用户有自己的命名空间,如:centos是存仓库中的镜像文件,admln/centos则 ...

  8. .net中的多线程

    一.多线程的概念        什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的,线程是程序中的一个执行流, ...

  9. BootStrap2学习日记22---点击展开

    先看效果: Code: <div class="accordion" id="accordion2"> <div class="ac ...

  10. C. Tavas and Karafs 二分查找+贪心

    C. Tavas and Karafs #include <iostream> #include <cstdio> #include <cstring> #incl ...