6

我有一个带有 GridLayoutManager 的 RecyclerView(支持 lib v7)。我更新适配器并制作 notifyItemMoved。如果项目源位置在屏幕上并且目标位置也在屏幕上 - 播放“移动动画”。如果项目位于屏幕外的位置(位置 1000 或任何其他远离视口的位置)并移入视口,它将显示“动画淡入淡出”。

看起来预测项目动画不起作用,尽管事实上 supportsPredictiveItemAnimations() 返回 true。难道我做错了什么?我应该重写一些方法来启用它吗?

我正在阅读 RecyclerView 的源代码,在 dispatchLayout 方法的 javadoc 中这样写:

  • PERSISTENT 视图被移动({@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)})
  • REMOVED 视图被移除 ({@link ItemAnimator#animateRemove(ViewHolder)})
  • 添加了视图({@link ItemAnimator#animateAdd(ViewHolder)})
  • 消失的视图被移出屏幕
  • 出现的视图在屏幕上移动

尽管如此,ItemAnimator 并不区分 ADDED 和 APPEARING。是否可以修复预测动画或至少使 APPEARING 动画看起来像“从屏幕动画外部移动”而留下 ADDED 动画?

4

2 回答 2

0

我有同样的问题。检查是否设置了 ItemAnimator。预测动画依赖于它,所以如果你打算使用 TransitionManager,然后创建空的 ItemAnimator 来启用预测动画。

您可以检查源代码(LinearLayoutManager:组:'com.android.support',名称:'recyclerview-v7',版本:'27.0.2')。

第 700-703 行:

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

state.willRunPredictiveAnimations() - 如果 ItemAnimator 为空,将返回 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.
于 2018-08-31T10:55:23.423 回答
0

您可以尝试覆盖以为getExtraLayoutSpace(RecyclerView.State state)管理LinearLayoutManager器提供预测动画的额外空间。

例子 :

@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
    return getHeight(); // add extra page for better predictive animations
}

额外的空间将在开始或结束时添加,具体取决于滚动视图的先前滚动增量。您可以查看 of 的实现onLayoutChildrenLinearLayoutManager获取更多详细信息。

于 2015-11-17T11:30:01.167 回答