[英]Android RecyclerView remove item animation bug
I'm trying to implement a ToDo list that contains a list and some other views below it on the activity page.我正在尝试实现一个 ToDo 列表,其中包含一个列表和活动页面上它下面的一些其他视图。
I am using a LinearLayout
for the entire page and a RecyclerView
for the list, alongside other views below the RecyclerView
( ImageView
, Buttons
...etc.)我对整个页面使用LinearLayout
,对列表使用RecyclerView
,以及RecyclerView
下方的其他视图( ImageView
、 Buttons
...等)
Here's my final view hierarchy:这是我的最终视图层次结构:
<LinearLayout>
<TextView />
<RecyclerView />
<Button />
<EditText />
<ImageView />
</LinearLayout>
I have implemented the RecyclerView
where I can add and remove items.我已经实现了RecyclerView
,我可以在其中添加和删除项目。 I am using a LinearLayoutManager
without specifying an ItemAnimator
so DefaultItemAnimator
is used.我正在使用LinearLayoutManager
而不指定ItemAnimator
因此使用DefaultItemAnimator
。
Adding items to the list works as expected.向列表中添加项目按预期工作。 My problem is that the page doesn't animate well when I remove an item from the RecyclerView
(by removing it from the dataset first then using RecyclerViewAdapter.notifyItemRemoved
).我的问题是,当我从RecyclerView
删除项目时,页面动画效果不佳(首先从数据集中删除它,然后使用RecyclerViewAdapter.notifyItemRemoved
)。
What happens is that the entire page snaps first to adapt to the new RecyclerView
height, and then the RecyclerView
item remove animation completes, which makes the behavior of the page look weird since all the views below the RecyclerView
snap up while the deleted item fades out but hasn't lost its height yet, then the remaining RecyclerView
items (below the deleted item) scroll up, looking like they're sliding up from under a wall.发生的情况是整个页面先对齐以适应新的RecyclerView
高度,然后RecyclerView
item remove 动画完成,这使得页面的行为看起来很奇怪,因为RecyclerView
下面的所有视图都对齐了,而删除的 item 淡出但还没有失去它的高度,然后剩余的RecyclerView
项目(在删除的项目下方)向上滚动,看起来它们是从墙下向上滑动的。
I tried to look for solutions on the web and couldn't find anything to solve my problem.我试图在网上寻找解决方案,但找不到任何可以解决我的问题的方法。
I have found this unanswered question describing the same problem.我发现这个未回答的问题描述了同样的问题。 Please refer to it in case my explanation wasn't clear enough.如果我的解释不够清楚,请参考它。
Anyone encountering the same issue?有人遇到同样的问题吗? Any suggestions?有什么建议?
Thanks.谢谢。
I had the same problem.我有同样的问题。 In my situation just this line helped:在我的情况下,这条线有帮助:
recyclerView.setHasFixedSize(true);
Try this one and check if it is working as your expectation:试试这个并检查它是否按您的期望工作:
recyclerView.setHasFixedSize(true);
recyclerView.setItemAnimator(new MyAnim());
public static class MyAnim extends RecyclerView.ItemAnimator {
@Override
public boolean animateDisappearance(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
return false;
}
@Override
public boolean animateAppearance(@NonNull RecyclerView.ViewHolder viewHolder, @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
return false;
}
@Override
public boolean animatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
return false;
}
@Override
public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
final float prevAlpha = ViewCompat.getAlpha(oldHolder.itemView);
ViewCompat.setAlpha(oldHolder.itemView, prevAlpha);
ViewCompat.setAlpha(newHolder.itemView, 0);
return true;
}
@Override
public void runPendingAnimations() {
}
@Override
public void endAnimation(RecyclerView.ViewHolder item) {
}
@Override
public void endAnimations() {
}
@Override
public boolean isRunning() {
return false;
}
}
Create subclass of RecyclerView
and override onTouchEvent
method like this:创建RecyclerView
子类并像这样覆盖onTouchEvent
方法:
@Override
public boolean onTouchEvent(MotionEvent e) {
if (findChildViewUnder(e.getX(), e.getY()) == null) {
return false;
}
return super.onTouchEvent(e);
}
Also, don't use wrap_content
as RecyclerView
height/width depending on your orientation.另外,不要根据您的方向使用wrap_content
作为RecyclerView
高度/宽度。
This way RecyclerView
has fixed size and does not cut off items while removing them.这样RecyclerView
具有固定的大小,并且在删除它们时不会切断项目。 Manipulation of onTouchEvent
method assures that part of RecyclerView
without items does not consumes click events and sends them to parent view of RecyclerView
.对onTouchEvent
方法的操作确保RecyclerView
没有项目的部分不会消耗点击事件并将它们发送到RecyclerView
父视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.