1、正常效果
我给RecycleView的添加了动画,正常情况是这样的(天气详情列表):
当点击一个城市会去加载天气详情列表,这个时候会启动进入的动画 是里面的Item从左边按顺序进来的一个效果

2、Bug情况
当我在动画还没播放结束时点击另一个城市,新加载的动画就出问题了,并不能正常运行

获得天气详情数据后的代码:
private fun initObserver() {
    mState.weathers.observe(viewLifecycleOwner) {
        Log.d(TAG, "initObserver: ${it.msg}")
        if (it.code == 0) {
            binding.weatherAdapter?.submitList(it.data)     //提交数据列表给适配器
            binding.rvWeather.scheduleLayoutAnimation()     //启动动画
            binding.imageView.startAnimation(imgEnterAnimation)
        } else {
            Toast.makeText(context, it.msg, Toast.LENGTH_SHORT).show()
        }
    }
}
我尝试了很多种方法去解决它,都没有效果:
- 在启动动画之前clearAnimation()
- 在启动动画之前对动画cancel(),reset()
- 监听动画的开始和结束
3、解决方法
用submitList的重载方法
public void submitList(@Nullable List<T> list, @Nullable final Runnable commitCallback) {
    mDiffer.submitList(list, commitCallback);
}
这里有一个提交的回调,在回调里面启动动画即可
private fun initObserver() {
    mState.weathers.observe(viewLifecycleOwner) {
        Log.d(TAG, "initObserver: ${it.msg}")
        if (it.code == 0) {
            binding.weatherAdapter?.submitList(it.data) {
                    binding.rvWeather.scheduleLayoutAnimation()
                }
            binding.imageView.startAnimation(imgEnterAnimation)
        } else {
            Toast.makeText(context, it.msg, Toast.LENGTH_SHORT).show()
        }
    }
}
造成的原因是因为 submitList会对改变了数据的Item调用notifyItem通知刷新,由于新旧数据的比较是在子线程进行的,所以主线程会执行我启动动画的代码,在动画启动过程中,我们还没看到效果,就收到了数据比较完成后的通知刷新notifyItem,于是出现了这样的bug

动画的使用
1、在res/anim下新建一个xml,adapter_enter_translate_anim
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--    <alpha-->
    <!--        android:duration="800"-->
    <!--        android:fromAlpha="0.3"-->
    <!--        android:toAlpha="1" />-->
    <!--    <scale-->
    <!--        android:duration="800"-->
    <!--        android:fromXScale="0.0"-->
    <!--        android:fromYScale="0.0"-->
    <!--        android:toXScale="1.0"-->
    <!--        android:toYScale="1.0" />-->
    <translate
        android:duration="300"
        android:fromXDelta="-100%"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="0" />
</set>
2、加载并设置动画
private fun initView() {
    val animation = AnimationUtils.loadAnimation(requireContext(), R.anim.adapter_enter_translate_anim)
    val animationController = LayoutAnimationController(animation, 0.1f)    //delay ->item间播放的延迟,300 * 0.1 = 30 毫秒
    animationController.order = LayoutAnimationController.ORDER_NORMAL         //item播放的顺序
    binding.rvWeather.layoutAnimation = animationController
}
3、启动动画
adapter.scheduleLayoutAnimation()






























