RecyclerView预测性项目动画不起作用(APPEARING)。

6
我有一个使用GridLayoutManager (support lib v7)的RecyclerView。我更新适配器并进行notifyItemMoved操作。如果项的源位置和目标位置都在屏幕上,“移动动画”将被播放。如果该项位于屏幕之外的位置(如位置1000或任何其他远离视口的位置),并移动到视口中,它将用“淡入动画”出现。
似乎无论supportsPredictiveItemAnimations()返回true与否,预测性项动画都不起作用。我做错了什么吗?我需要重写某些方法以启用它吗?
我正在阅读RecyclerView的源代码,并在dispatchLayout方法的javadoc中写道:
持续存在的视图移动(ItemAnimator#animateMove(ViewHolder, int, int, int, int))
移除的视图被删除(ItemAnimator#animateRemove(ViewHolder))
添加的视图被添加(ItemAnimator#animateAdd(ViewHolder))
消失的视图移到屏幕外
出现的视图移到屏幕上
尽管如此,ItemAnimator没有区分已添加和已显示。
是否可能修复预测性动画,或者至少使出现的动画看起来像“从屏幕外移动的动画”,同时保留已添加的动画?

我认为出现(appearing)通常用于视图可见性的更改,而不是添加到适配器中。 - stkent
@stkent 这里是Javadoc,你可以查看:源代码 - Vitaliy Lozoviy
啊,我明白了。我记得读过一篇讨论淡入问题的文章。详见http://wiresareobsolete.com/2015/02/recyclerview-layoutmanager-3/。 - stkent
2个回答

0

我曾经遇到过同样的问题。请检查是否已设置ItemAnimator。预测动画依赖于它,因此如果您要使用TransitionManager,则需要创建空的ItemAnimator以启用预测动画。

您可以检查源代码(LinearLayoutManager:group:'com.android.support',name:'recyclerview-v7',version:'27.0.2')。

700-703行:

if (!state.willRunPredictiveAnimations() ||  getChildCount() == 0 || state.isPreLayout()
            || !supportsPredictiveItemAnimations()) {
        return;
    }

state.willRunPredictiveAnimations() - 如果ItemAnimator为null,则返回false。

EmptyItemAnimator.java

public class EmptyItemAnimator extends RecyclerView.ItemAnimator {
@Override
public boolean isRunning() {
    return false;
}

@Override
public void endAnimations() {}

@Override
public boolean animatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
    return false;
}

@Override
public void endAnimation(RecyclerView.ViewHolder item) {}

@Override
public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
    return false;
}

@Override
public void runPendingAnimations() {}

@Override
public boolean animateAppearance(@NonNull RecyclerView.ViewHolder viewHolder, @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
    return false;
}

@Override
public boolean animateDisappearance(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
    return false;
}}

现在你可以尝试:

TransitionManager.beginDelayedTransition(recyclerView);
recyclerViewAdapter.notifyItem... //add, remove, change etc.

0
你可以尝试重写LinearLayoutManagergetExtraLayoutSpace(RecyclerView.State state)方法,为管理器提供额外的空间以进行预测动画。
示例:
@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
    return getHeight(); // add extra page for better predictive animations
}

额外的空间将根据滚动视图之前的滚动增量添加在开头或结尾。您可以查看LinearLayoutManageronLayoutChildren实现以获取更多详细信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接