我正在使用 SwipeRefreshLayout
来刷新我的 Activity 。布局看起来像这样,非常简单:
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.core.widget.NestedScrollView
android:id="@+id/feedBase"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/linearLayoutFeed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
linearLayoutFeed
在刷新时以编程方式添加一些 View ,并在线加载数据。当该过程完成时,我调用 isRefreshing=false
(Java 等效项是 setRefreshing(false)
。这似乎是停止它的唯一方法,这也是在其他问题中建议。但是,这不起作用。
刷新指示器永远不会消失。我检查了调试器,操作完成并调用了对 isRefreshing=false
的回调。之后,我检查了 isRefreshing
的值,它正确显示了 false
。
这是我运行的(简化的)代码:
swipeRefreshLayout.setOnRefreshListener {
loadData() { // callback
(context as AppCompatActivity).runOnUiThread {
swipeRefreshLayout.isRefreshing = false
}
}
}
private fun loadData(callback: () -> Unit) {
Thread {
try {
// loading my data
} catch (e: Exception) {
e.printStackTrace()
} finally {
callback.invoke()
}
}.start()
}
这基本上是我在这里和其他网站上的其他问题/答案中读到的内容。但是,setRefreshing
的文档指出:
Notify the widget that refresh state has changed. Do not call this when refresh is triggered by a swipe gesture.
我一直在寻找其他函数来调用以结束刷新或只是不设置刷新,但我没有找到任何其他方法,也没有设置它工作。
现在是复杂的部分:
SwipeRefreshLayout
被设置为带有 TabLayout
的 ViewPager
。 SwipeRefreshLayout
仅在第一页上。现在,当我第一次刷新它时,刷新指示器不会消失。但是当我将页面切换到最后一页然后返回到第一页并刷新时,刷新指示器在完成后消失。
基本上是这样
- 已选择第 1 页
- 拉手势
- 第 1 页已刷新,刷新指示器未消失
- 已选择第 5 页
- 已选择第 1 页,刷新指示器消失
- 拉手势
- 第 1 页已刷新,刷新指示器消失
我不太理解这种行为,希望得到任何帮助以找出这里出了什么问题。我不认为我用页面切换改变了任何应该改变 SwipeRefreshLayout
行为的东西,但不知何故它确实改变了。
编辑
回答评论中的问题:
- 这一切都发生在主线程中吗?
- loadData 启动一个新线程。在该线程中,我通过
runOnUiThread
在主线程中执行某些操作,当然如上所示,回调也是runOnUiThread
- loadData 启动一个新线程。在该线程中,我通过
- 您是否尝试将状态更改发布到小部件? (想想:swipeLayout.post { swipeLayout.isRefreshing = false }
- 是的,我试过postDelayed,有1000ms和5000ms
- 您是否尝试在滑动刷新时调用 enabled = false?
- 是的,基本上发生了同样的事情。刷新指示器保持原位。当我按上述方式切换页面并尝试再次刷新时,正如预期的那样,它根本不起作用。
编辑2
我刚刚注意到,虽然出现此错误,但我可以继续滑动。当第一个刷新指示器仍然存在时,它后面的第二个刷新指示器会出现和消失。
最佳答案
看来我的某些基础知识有误,或者至少对我的 Activity/布局/ View 的构建方式有错误的理解。
加载指示器没有消失的原因是,它确实消失了。他们中的一个至少做到了。
我以为我有一个 SwipeRefreshLayout,但实际上有两个!但我只停用了其中一个。
我为布局充气的自定义 View 本身就是一个 SwipeRefreshLayout。所以我认为我有这个层次结构:
SwipeRefreshLayout
->NestedScrollView
-->LinearLayout
但我实际上有这样的层次结构:
SwipeRefreshLayout (View itself)
->SwipeRefreshLayout (from Layout)
-->NestedScrollView
--->LinearLayout
所以我所做的是停止刷新我从 View 而不是 View 本身膨胀的 SwipeRefreshLayout。 因此,显而易见的解决方法是从布局文件中删除 SwipeRefreshLayout 并相应地管理 View 本身。
话虽这么说,我还是不明白文档为什么这么说
Notify the widget that refresh state has changed. Do not call this when refresh is triggered by a swipe gesture.
这让我误会了问题所在。
此外,我仍然不太明白为什么如上所述,当我来回滑动时,这种情况只发生一次,然后不再发生。我假设是因为 View 本身在重新聚焦时没有重绘刷新指示器,即使它仍然是“Activity 的”。所以它在那里但看不见,只是没有得到刷新/重绘。虽然不确定。
关于java - 停止 SwipeRefreshLayout 刷新动画,尽管 setRefresh(false)/isRefreshing=false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57920267/