Ошибка выполнения LayoutAnimation в RecyclerView при срабатывании SwipeRefreshLayout - PullRequest
2 голосов
/ 25 марта 2019

Я пытаюсь выполнить пользовательскую анимацию в моем RecyclerView, используя свойство XML android:layoutAnimation.

Проблема заключается в следующем: когда я заполняю свой адаптер непосредственно в onCreate() действия, анимация срабатывает нормально.Однако, когда я пытаюсь заполнить свой recyclerView из SwipeRefreshLayout.setOnRefreshListener, анимация не запускается правильно.

Понятия не имею, что не так.

Зависимости

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-файлы

Activity 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>

Мой код в упрощенной версии

Этот код вызывает 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)
    }
}

в обоих фрагментах кода(это в основном то же самое), я считаю, что RecyclerView переходит из пустого состояния в заполненное состояние .Есть ли какая-либо разница в перспективе пользовательского интерфейса, если я заполняю свой адаптер внутри обратного вызова setOnRefreshListener или внутри onCreate?

Edit : приведенные выше фрагменты отличаются от исходной кодовой базы простосделать объяснение проще.Я не хочу знать о производительности в этом вопросе.Я хотел бы знать, почему анимация не работает во втором фрагменте и прекрасно работает в первом фрагменте.

1 Ответ

0 голосов
/ 25 марта 2019

В основном первый фрагмент только должен работать, если вы отправляете свой список внутри обновления, то есть:

postListSwipeRefreshLayout.setOnRefreshListener {
  adapter.submitList(postList)
}

И второй фрагмент кода не должен вызывать анимацию, потому что каждый раз, когда выобновляя макет, вы создаете новый экземпляр адаптера , что делает адаптер не может наблюдать за изменениями.

Я не знаю, почему вы создаете новый экземпляр каждый раз, когда обновляете макет, однако это потребляет память с бесполезными экземплярами.

В заключение: Вы должны создавать экземпляры только один раз и использовать их столько, сколько сможете вместо создания нового.

...