【问题标题】:Android RecyclerView remove item animation bugAndroid RecyclerView 移除item动画的bug
【发布时间】:2017-03-08 06:58:06
【问题描述】:

我正在尝试在活动页面上实现一个 ToDo 列表,其中包含一个列表和它下面的一些其他视图。

我对整个页面使用LinearLayout,对列表使用RecyclerView,以及RecyclerView下方的其他视图(ImageViewButtons...等)

这是我的最终视图层次结构:

<LinearLayout>
    <TextView />
    <RecyclerView />
    <Button />
    <EditText />
    <ImageView />
</LinearLayout>

我已经实现了RecyclerView,我可以在其中添加和删除项目。 我使用的是LinearLayoutManager,但没有指定ItemAnimator,所以使用了DefaultItemAnimator

向列表中添加项目按预期工作。我的问题是,当我从RecyclerView删除一个项目时,页面动画效果不佳(首先从数据集中删除它,然后使用RecyclerViewAdapter.notifyItemRemoved)。

发生的情况是整个页面首先捕捉以适应新的RecyclerView 高度,然后RecyclerView 项目删除动画完成,这使得页面的行为看起来很奇怪,因为所有视图都低于@987654336 @ 在已删除项目淡出但尚未失去其高度时抢购,然后剩余的 RecyclerView 项目(已删除项目下方)向上滚动,看起来像是从墙下向上滑动。

我试图在网上寻找解决方案,但找不到任何可以解决我的问题的方法。

我发现this unanswered question 描述了同样的问题。如果我的解释不够清楚,请参考它。

有人遇到同样的问题吗?有什么建议吗?

谢谢。

【问题讨论】:

  • 所以你想在项目更改时删除动画吗?
  • 不使用 notifyDataSetChanged(),而是使用 notifyItemRemoved()。 NotifyDataSetChanged 重建 RecyclerView 中的整个数据集,因此所有行都被重绘。而 notifyItemRemoved() 或 notifyItemRangeChanged() 只会刷新已更改的项目,因此生涩的动作将消失。
  • @Divyesh 我不想删除动画,我只是希望当我从 RecyclerView 删除一个项目时整个页面的动画效果很好。我的意思是我希望页面在翻译之前等待 RecyclerView 项目动画完成。
  • @Rachit 我正在使用 notifyItemRemoved,我在问题中明确提到了这一点。
  • @Rachit 不,我想你看错了。不过都很好。有关如何解决我的问题的任何建议?

标签: android android-layout animation android-recyclerview android-animation


【解决方案1】:

我遇到了同样的问题。在我的情况下,这条线有帮助:

recyclerView.setHasFixedSize(true);

【讨论】:

    【解决方案2】:

    试试这个并检查它是否按您的预期工作:

    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;
            }
        }
    

    【讨论】:

    • 那行不通。问题不在于 RecyclerView 项目本身的动画,问题在于页面如何处理 RecyclerView 下面的所有其他项目......第二个我删除了一个项目 RecyclerView 下的所有视图 snap 以适应新的 RecyclerView在项目的删除动画完成之前计算的高度(项目删除后)。
    【解决方案3】:

    创建RecyclerView 的子类并像这样覆盖onTouchEvent 方法:

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        if (findChildViewUnder(e.getX(), e.getY()) == null) {
            return false;
        }
        return super.onTouchEvent(e);
    }
    

    另外,不要将wrap_content 用作RecyclerView 高度/宽度,具体取决于您的方向。

    这种方式RecyclerView 具有固定大小,并且在移除项目时不会切断它们。对onTouchEvent 方法的操作确保RecyclerView 中没有项目的部分不会消耗点击事件并将它们发送到RecyclerView 的父视图。

    【讨论】:

      猜你喜欢
      • 2016-07-07
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多