拓展开源库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#语 ...
随机推荐
- JDBC连接各种数据库的方法(经典)
1)连接Oracle 8/8i/9i/10g/11g(thin模式) Class.forName("oracle.JDBC.driver.OracleDriver").newIns ...
- Codeforces Round #310 (Div. 1) B. Case of Fugitive set
B. Case of Fugitive Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/555/p ...
- ORA-01722: invalid number
---问题 select owner,index_name,DEGREE from DBA_INDEXES where DEGREE>1 ...
- Citrix 服务器虚拟化之二十八 XenApp6.5发布文档内容
Citrix 服务器虚拟化之二十八 XenApp 6.5发布文档内容 XenApp可发布以下类型的资源向用户提供信息访问,这些资源可在服务器或桌面上虚拟化: 1) 服务器桌面:发布场中服务器的整个 ...
- 放肆的使用UIBezierPath和CAShapeLayer画各种图形
CAShapeLayer 是 CALayer 的子类,但是比 CALayer 更灵活,可以画出各种图形,当然,你也可以使用其他方式来画,随你. 杂谈 在 CAShapeLayer 中,也可以像 CAL ...
- iOS开发——高级UI之OC篇&UIdatePicker&UIPickerView简单使用
UIdatePicker&UIPickerView简单使用 /***************************************************************** ...
- Flex博客
http://blog.csdn.net/xingfeng0501/article/details/7533426
- 信号之sigaction函数
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(或同时执行这两种操作). #include <signal.h> int sigaction( int signo, c ...
- Scala初体验
因为工作中要用到Scala了,本来前面自己还在学习Storm的,没有办法,先把Scala和Spark的这些内容学完在回去看Storm吧! 既然我们要学习Scala,那么我们不禁的要问了,什么是Scal ...
- IOS 开发过程中的 消息通知 小红点
大致分为两种方法:系统方法和自定义方法 系统方法: 系统自带的方法可以显示具体的消息数量,这个就是苹果设备常见的小红点.实现思路如下: NSArray *tabBarItems = self.navi ...