java - 停止 SwipeRefreshLayout 刷新动画,尽管 setRefresh(false)/isRefreshing=false

标签 java android android-layout kotlin swiperefreshlayout

我正在使用 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 被设置为带有 TabLayoutViewPagerSwipeRefreshLayout 仅在第一页上。现在,当我第一次刷新它时,刷新指示器不会消失。但是当我将页面切换到最后一页然后返回到第一页并刷新时,刷新指示器在完成后消失。

基本上是这样

  • 已选择第 1 页
  • 拉手势
  • 第 1 页已刷新,刷新指示器未消失
  • 已选择第 5 页
  • 已选择第 1 页,刷新指示器消失
  • 拉手势
  • 第 1 页已刷新,刷新指示器消失

我不太理解这种行为,希望得到任何帮助以找出这里出了什么问题。我不认为我用页面切换改变了任何应该改变 SwipeRefreshLayout 行为的东西,但不知何故它确实改变了。

编辑

回答评论中的问题:

  • 这一切都发生在主线程中吗?
    • loadData 启动一个新线程。在该线程中,我通过 runOnUiThread 在主线程中执行某些操作,当然如上所示,回调也是 runOnUiThread
  • 您是否尝试将状态更改发布到小部件? (想想: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/

相关文章:

Android 自定义 View - 自定义属性错误

android - 如何处理重复自定义组件的点击/触摸?

java - 线程中出现异常 "Image Animator 3"java.lang.OutOfMemoryError : Java

java - 从一种 HTML 转换为另一种 HTML

android - 即使本地缓存可用且未更改,Firebase 单值监听器也会调用服务器

android - 如何缩放大于 4096 像素的位图?

android - ScrollView 中的 RecyclerView 不起作用

java - 基于组件的 MVC 框架中的控制较少意味着什么

java - 了解简单 CRUD 网站中对 struts 2 和公共(public)链的需求

android - Phone Number 和 Email 验证都可以在 Firebase 中应用吗?