滚动时动画RecyclerView

rek*_*ire 24 android android-animation android-recyclerview

滚动时有没有办法为RecyclerView的元素设置动画?

我看了看DefaultItemAnimatorRecyclerView.ItemAnimator,但动画似乎如果数据集已经改变了只叫,请纠正我,如果我错了.

我什么RecyclerView.ItemAnimator.animateMove()时候打电话有点困惑?我在该课程中添加了一些断点,但没有一个断点停止我的应用程序.

但是回到我的问题,我如何为RecyclerView设置动画?我希望某些元素具有另一个不透明度,取决于一些自定义规则.


我做了一些更多的动画似乎动画移动正是我正在寻找的.这些方法是从dispatchLayout().这是该方法的javadoc:

layoutChildren()周围的包装器,用于处理由布局引起的动画更改.动画假设有五种不同类型的项目:
PERSISTENT:项目在布局之前和之后可见
REMOVED:项目在布局之前可见并且被应用程序删除
ADDED:项目在布局之前不存在并且由应用程序
DISAPPEARING:项目存在于数据集之前/之后,但在布局过程中从可见变为不可见(它们被移出屏幕作为其他更改的副作用)
出现:数据集中存在项目之前/之后,但在布局过程中从不可见变为可见(它们在屏幕上移动作为其他变化的副作用)
整体方法确定布局之前/之后存在哪些项目并推断五个中的一个以上状态为每个项目.然后相应地设置动画:
移动PERSISTENT视图({@link ItemAnimator #animateMove(ViewHolder,int,int,int,int)})删除REMOVED视图({@link ItemAnimator #animateRemove(ViewHolder)})
ADDED视图添加({@link ItemAnimator#animateAdd(ViewHolder)})
DISAPPEARING视图移出屏幕
在屏幕上移动视图

到目前为止,我正在寻找PERSISTENT,DISAPPEARING和APPEARING,但是这个方法从未被调用,因为这里有这一行:

boolean animateChangesSimple = mItemAnimator != null && mItemsAddedOrRemoved
            && !mItemsChanged;
Run Code Online (Sandbox Code Playgroud)

mItemsAddedOrRemoved总是假的,所以没有达到任何回调.知道如何正确设置设置标志吗?

rek*_*ire 9

我最终使用了OnScrollListener一个自定义animate()方法并使其动画化.在我的情况下,代码只需2毫秒,因此60fps没有问题.

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(int newState) {
        if(newState == RecyclerView.SCROLL_STATE_IDLE) {
            // special handler to avoid displaying half elements
            scrollToNext();
        }
        animate();
    }

    @Override
    public void onScrolled(int dx, int dy) {
        animate();
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 你可以添加更多的代码 - 比如scrollToNext吗? (2认同)

Vin*_*kar 6

我是这样做的.可以帮助别人.我不知道这是否是最好的方式,但对我来说效果很好.

更新: 要修复快速滚动行为,请覆盖onViewDetachedFromWindow适配器的方法并调用clearAnimation动画视图(在本例中holder.itemView.clearAnimation()).

up_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
    android:fromXDelta="0%" android:toXDelta="0%"
    android:fromYDelta="100%" android:toYDelta="0%"
    android:duration="400" />
</set>
Run Code Online (Sandbox Code Playgroud)

down_from_top.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
    android:fromXDelta="0%" android:toXDelta="0%"
    android:fromYDelta="-100%" android:toYDelta="0%"
    android:duration="400" />
</set>
Run Code Online (Sandbox Code Playgroud)

最后把这段代码放进去onBindViewHolderrecyclerView.创建一个名为lastPosition的字段并将其初始化为-1.

Animation animation = AnimationUtils.loadAnimation(context,
            (position > lastPosition) ? R.anim.up_from_bottom
                    : R.anim.down_from_top);
    holder.itemView.startAnimation(animation);
    lastPosition = position;
Run Code Online (Sandbox Code Playgroud)