RecyclerView预测项目动画不起作用(出现)

问题描述 投票:4回答:2

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

尽管supportPredictiveItemAnimations()返回true,但看起来预测项目动画仍无法正常工作。难道我做错了什么?我应该覆盖一些方法来启用它吗?

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

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

然而,ItemAnimator不区分ADDED和APPEARING。是否有可能修复预测动画或至少使APPEARING动画看起来像“从屏幕动画外移动”原样提供ADDED动画?

android android-recyclerview gridlayoutmanager
2个回答
0
投票

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

例如:

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

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


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。

empty item animator.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.
© www.soinside.com 2019 - 2024. All rights reserved.