我有一个带有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动画?
您可以尝试覆盖getExtraLayoutSpace(RecyclerView.State state)
的LinearLayoutManager
,为管理员提供预测动画的额外空间。
例如:
@Override
protected int getExtraLayoutSpace(RecyclerView.State state) {
return getHeight(); // add extra page for better predictive animations
}
根据滚动视图的上一个滚动增量,将在开头或结尾添加额外的空间。您可以查看onLayoutChildren
的LinearLayoutManager
的实现以获取更多详细信息。
我有同样的问题。检查您是否设置了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.