【问题标题】:Problem performing LayoutAnimation in RecyclerView when triggered by SwipeRefreshLayout由 SwipeRefreshLayout 触发时在 RecyclerView 中执行 LayoutAnimation 时出现问题
【发布时间】:2019-03-25 04:11:05
【问题描述】:

我正在尝试使用 XML 属性 android:layoutAnimation 在我的 RecyclerView 中执行自定义动画。

问题是:当我直接在活动的onCreate() 中填充我的适配器时,动画会正常触发。但是,当我尝试从 SwipeRefreshLayout.setOnRefreshListener 填充我的 recyclerView 时,动画未正确触发。

我不知道出了什么问题。

依赖关系

implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha04'

XML 文件

活动 XML:

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/postListRecyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:layoutAnimation="@anim/layout_animation_enter_up"
        android:paddingTop="8dp"
        android:paddingBottom="8dp" />

layout_animation_enter_up.xml:

<layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/item_animation_enter_up"
    android:animationOrder="normal"
    android:delay="15%" />

item_animation_enter_up.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="600">

    <translate
        android:fromYDelta="50%p"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:toYDelta="0" />

    <alpha
        android:fromAlpha="0"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:toAlpha="1" />

</set>

My Code 简化版

此代码正确触发了 layout_animation_enter_up 动画:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_post_list)

    val adapter = PostsAdapter()
    postListRecyclerView.adapter = adapter
    val dummyData = Post(1, "Title", "Body", 1, "Name")
    val postList = listOf(dummyData, dummyData, dummyData, dummyData, dummyData, dummyData, dummyData)

    adapter.submitList(postList)
}

此代码不会触发 layout_animation_enter_up 动画:

override fun onCreate(savedInstanceState: Bundle?) {
    postListSwipeRefreshLayout.setOnRefreshListener {
        val adapter = PostsAdapter()
        postListRecyclerView.adapter = adapter
        val dummyData = Post(1, "Title", "Body", 1, "Name")
        val postList = listOf(dummyData, dummyData, dummyData, dummyData, dummyData, dummyData, dummyData)

        adapter.submitList(postList)
    }
}

在两个代码 sn-ps(基本相同)中,我认为 RecyclerView 正在从空状态变为填充状态。如果我在setOnRefreshListener 回调或onCreate 内填充我的适配器,UI 透视图有什么不同吗?

编辑:上面的 sn-ps 与原始代码库不同,只是为了使解释更容易。我不想知道这个问题的表现。我想知道为什么动画在第二个 sn-p 中不起作用,而在第一个 sn-p 中可以正常工作。

【问题讨论】:

    标签: android android-layout android-recyclerview android-animation swiperefreshlayout


    【解决方案1】:

    如果您在刷新中提交列表,基本上第一个 sn-p only 应该起作用,即:

    postListSwipeRefreshLayout.setOnRefreshListener {
      adapter.submitList(postList)
    }
    

    第二个 sn-p 代码不应触发动画,因为每次刷新布局时都会创建一个新适配器实例,这会使适配器无法观察到更改。

    我不知道为什么每次刷新布局时都要创建一个新实例,但是这会消耗无用实例的内存。

    总结:您应该只创建一次实例,并尽可能多地重复使用它,而不是创建新实例。

    【讨论】:

    • 您好易卜拉欣,感谢您的回复。上面的 sn-ps 与原始代码库不同,只是为了使解释更容易(我在帖子中添加了此信息)。考虑到 RecyclerView 在这两种情况下都从空状态变为填充状态,我的目的是了解为什么动画在第一个 sn-p 而不是第二个中起作用。我已经尝试使用适配器的一个实例,但我仍然遇到同样的问题 =(
    • @PhellipeSilva 好吧,我认为这里没有更多的潜力,您正在创建新的适配器并将新的适配器实例设置为 recycleView,这会产生非动画行为。如果您提交了不同的列表项,则通过在onRefresh 中提交列表应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多