拓展开源库SwipeToLoadLayout实现EmptyView和Empty时自动禁用LoadMore
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的更多相关文章
- 各种有用的PHP开源库精心收集
转自:http://my.oschina.net/caroltc/blog/324024 摘要 各种有用的PHP开源库精心收集,包含图片处理,pdf生成,网络协议,网络请求,全文索引,高性能搜索,爬虫 ...
- 在别的地方看的<<给程序员介绍一些C++开源库>>,记录给大家共同学习
首先说明这篇文章不是出自我手,大家共同学习. 引用地址:http://oss.org.cn/?action-viewnews-itemid-61998. C++开源库,欢迎补充. C++在“商业应用” ...
- [转贴]C++开源库
C++在“商业应用”方面,曾经是天下第一的开发语言,但这一 桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C# ...
- 33 个 2017 年必须了解的 iOS 开源库
本文翻译自Medium,原作者为Pawe? Bia?ecki 照片版权:(Unsplash/Markus Pe) 你好,iOS 开发者们!我的名字叫 Pawe?,我是一个独立 iOS 开发者,并且是 ...
- C++开源库,欢迎补充。
转载自:http://blog.csdn.net/kobejayandy/article/details/8681741 C++在"商业应用"方面,曾经是天下第一的开发语言,但这一 ...
- 33 个 2017 年必须了解的 iOS/swift 开源库第三方库
本文翻译自Medium,原作者为 Paweł Białecki<img src="https://pic3.zhimg.com/v2-c786777447261347b0d97 ...
- ios很好的开源库
Tim9Liu9/TimLiu-iOS 自己总结的iOS.mac开源项目及库,持续更新.. 目录 UI 下拉刷新 模糊效果 AutoLayout 富文本 图表 表相关与Tabbar 隐藏与显示 HUD ...
- Android 使用开源库载入网络图片
Android 使用开源库载入网络图片,使用开源库载入图片.单击listview弹出popupwindow弹出框详情查看: Android 单击listview弹出popupwindow弹出框 ,里面 ...
- C++开源库,欢迎补充
C++在“商业应用”方面,曾经是天下第一的开发语言,但这一桂冠已经被java抢走多年.因为当今商业应用程序类型,已经从桌面应用迅速转移成Web应 用.当Java横行天下之后,MS又突然发力,搞出C#语 ...
随机推荐
- VC++ 网络编程总结(二)
2.基本的Windows Socket API编程 需要在程序中添加下面的包含语句:#include <winsock2.h> #pragma comment( lib, " ...
- SGU 532. Building Foundation 暴力
532. Building Foundation 题目连接: http://acm.sgu.ru/problem.php?contest=0&problem=532 Description A ...
- 32位Windows7上8G内存使用感受+xp 32位下使用8G内存 (转)
32位Windows7上8G内存使用感受+xp 32位下使用8G内存 博客分类: Windows XPWindowsIE企业应用软件测试 我推荐做开发的朋友:赶快加入8G的行列吧....呵呵..超爽 ...
- 微软ASP.NET网站部署指南(4):配置项目属性
1. 综述 有些部署设置能够在项目属性里设置的,而且保持到项目文件中(.csproj或.vbproj). 大多数情况下.你都能够在Visual Studio 选择项目属性Project Proper ...
- PHP 页面编码声明方法(header或meta)
本文为大家介绍了二种页面编码的声明方法,一种是使用php中的header函数来向客户端发送header头,一种是使用html中的meta标签来生明页面编码,本文分别对他们如何使用进行了说明,感兴趣的同 ...
- C#如何读写和创建INI文件
在做项目过程中,有时需要保存一些简单的配置信息,可以使用xml,也可以使用INI文件.下面是C#中读取INI的方法,相信大部分朋友都使用过这种方式.INI文件的存储方式如下, [section] ke ...
- highcharts笔记 highcharts学习 highcharts用法
标示线:plotLines : 绘制线:
- win7配置nginx+php步骤
1.下载nginx: http://www.nginx.cn/nginx-download 2.下载php : http://www.php.net/downloads.php (线程安全与非安全参 ...
- SimpleUrlHandlerMapping 处理器映射的配置--转
http://blog.csdn.net/rainier001/article/details/6860491 <?xml version="1.0" encoding=&q ...
- mkinitrd 与 mkinitramfs
转载:http://blog.csdn.net/mayouyang/article/details/3997849 在进行内核编译时,需要进行制作initrd.img.在Fedora下面一般是用mki ...