概述:
很多场景需要使用上拉加载和下拉刷新功能,但可能会出现SmartRefresh嵌套ScrollView然后再嵌套RecyclerView然后出现加载动画和内容重叠问题。该问题出现是因为SmartRefresh只能控制它的子控件进行上拉加载,所以作为它的孙子RecyclerView则不受它控制,而我们就是希望作为孙子的RecyclerView的加载数据受SmartRefresh控制。网上有很多解决方法,大部分是解决RecyclerView和ScrollView滑动冲突这块,但是需要重写控件非常麻烦,有没有更简单的方法呢?翻阅SmartRefresh官方的问题文档,发现其API提供加载动画结束状态标志。
## 1.获取当前状态?isRefreshing(),isLoading() 不见了?(1.1.0以上版本,2.x 回归)
版本的迭代,刷新的状态越来越多,仅仅 isRefreshing(),isLoading() 已经无法满足要求,在1.0.5版本之后本库直接将
内部 State 开放出来,并在1.0.5版本标记 isRefreshing(),isLoading() 过期,鼓励大家使用 getState 来代替。将在
1.1.0版本删除这两个API。
getState 比前两个方法更有用,具体参考下面代码。
~~~java
refreshLayout.getState() == RefreshState.None //空闲状态
refreshLayout.getState() == RefreshState.Loading//代替 isLoading
refreshLayout.getState() == RefreshState.Refreshing//代替 isRefreshing
refreshLayout.getState().isDragging //判断是否正在拖拽刷新控件(非拖拽列表)
refreshLayout.getState().isFinishing //判断动画是否正在结束
refreshLayout.getState().isHeader //判断当前是否处于 Header 的一系列状态中
refreshLayout.getState().isFooter //判断当前是否处于 Footer 的一系列状态中
refreshLayout.getState().isOpening // 等同于 isLoading || isRefreshing
~~~
## 2.
思路:
监听加载动画的结束,根据结束标志来控制RecyclerView的数据加载时机。创建一个新线程,通过while循环进行结束标志判断,如果结束则进行数据的加载。后发现对UI的更改必须在UI线程中进行,所以必须使用android的消息机制来进行线程间的通信。
参考:
注意:
这种方式修改后,每次上拉加载都会出现回弹动画,使用感上没有多大影响。如果不想这样的话,只能说尽量避免嵌套的情况了。
步骤:
//找到该控件
@BindView(R.id.srl_index)
private lateinit var mRefreshLayout: SmartRefreshLayout
//需要添加的新数据
private lateinit var newDatas : MutableList<IndexCaseListData.Data>
//接收新线程传递的消息,然后给RecyclerView添加新数据
private var handler = object : Handler(){
override fun handleMessage(msg: Message) {
if(msg.what == COMPLETED){
indexAdapter.addData(newDatas)
}
}
}
//当上拉加载触发时,对loadMore方法进行修改,开启新线程进行结束标志监听
mRefreshLayout.setOnLoadMoreListener { refreshLayout ->
currentPage++
loadMore(currentPage)
}
//上拉加载,只发起列表请求
fun loadMore(pageNum: Int) {
//rxhttp获取后台数据
RxHttp.postJson(Constant.INDEX_CASE)
.addHeader(Constant.TOKEN, AppSharedPreferences.getInstance(me).token)
.add("limit", Constant.HOME_PAGESIZE)
.add("page", pageNum)
.asClass(IndexCaseListData::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ s ->
Log.e("首页案例列表调试", "success:" + s.data)
//将数据绑定到列表中
// list.addAll(s.data)
if (s.data.size == 0) { //没有数据
Log.e("首页案例列表调试", "数据是否为0:" + s.data.size)
mRefreshLayout.finishLoadMore(0, true, true)
}
if (s.data != null && s.data.size != 0) {
mRefreshLayout.finishLoadMore(800, true, false)
//开辟新线程来进行监听判断动画是否结束,再来添加数据
var mRunnable = Runnable { run{
//通过while循环进行监听
while (true){
if(mRefreshLayout.state == RefreshState.None){
//子线程通知主线程进行UI修改操作
var msg = Message()
msg.what = COMPLETED
handler.sendMessage(msg)
break
}
}
} }
newDatas = s.data
Thread(mRunnable).start()
}
}, { throwable ->
Log.e("QQ", "error:" + throwable)
mRefreshLayout.finishLoadMore(false)
})
}
网友评论