【问题标题】:How to remove all items in RecyclerView Adapter with Animation如何使用动画删除 RecyclerView 适配器中的所有项目
【发布时间】:2017-08-11 20:10:11
【问题描述】:

如果用户滑动,我想删除一个项目,如果用户单击 deleteAll 按钮,我想删除 RecyclerView 中的所有项目,我尝试访问每个视图并添加一个动画,但我现在不知道如何,我在创建中添加动画因为适配器给了我onBindViewHolder 中的每个视图持有者,这是我的适配器

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context context;
List<String> stringList;
public MyAdapter(Context context, List<String> stringList) {
    this.context = context;
    this.stringList = stringList;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context)
            .inflate(R.layout.item,parent,false);

    MyViewHolder viewHolder = new MyViewHolder(view);
    return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
    holder.itemView.startAnimation(animation);
    holder.bind(stringList.get(position));
}


@Override
public int getItemCount() {
    return stringList.size();
}



public void dismiss(int adapterPosition) {
            stringList.remove(adapterPosition);
            this.notifyItemRemoved(adapterPosition);
    }

public void removeItem(int position) {
    this.stringList.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, getItemCount() - position);
}




class MyViewHolder extends RecyclerView.ViewHolder
        implements View.OnClickListener {
    TextView textView;
    String data;
    public MyViewHolder(View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.text);
        itemView.setOnClickListener(this);
    }
    public void bind(String data) {
        this.data = data;
        textView.setText(data);
    }

    @Override
    public void onClick(View view) {
        stringList.remove(data);
        notifyDataSetChanged();
    }

}}

我的RecyclerView 和主要活动中的适配器以及我如何处理全部删除,但问题是我如何添加动画

  adapter = new MyAdapter(this,myList);
    ItemTouchHelper.Callback callback = new SwipeHelper(adapter);
    ItemTouchHelper helper = new ItemTouchHelper(callback);
    recyclerView.setAdapter(adapter);
    helper.attachToRecyclerView(recyclerView);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            for (int i = myList.size()-1 ; i >= 0 ; i--){
                adapter.removeItem(i);
            }
            //recyclerView.removeItemDecoration();
        }
    });

【问题讨论】:

  • 你到底要做什么动画?是不是类似于gmail的滑动动画,你想用手机删除邮件?
  • 是的,当用户单击删除所有项目时,我想要从回收站视图中滑出所有项目
  • RecyclerView 中做动画的正确方法是通过ItemAnimator。不要将动画放在适配器中,因为它不是适配器对动画布局更改的责任。查看此视频:link。有关更多详细信息,请查看此存储库:repo

标签: java android animation android-recyclerview android-animation


【解决方案1】:

我通过在该项目上模拟滑动动画来一次删除一个项目,并在删除下一个项目之前发布延迟,依此类推直到RecyclerView的最后一个项目

第一步:

在您的包含全部清除按钮和RecyclerView 实例的活动中:创建单项删除方法

private void deleteItem(View rowView, final int position) {

    Animation anim = AnimationUtils.loadAnimation(requireContext(),
            android.R.anim.slide_out_right);
    anim.setDuration(300);
    rowView.startAnimation(anim);

    new Handler().postDelayed(new Runnable() {
        public void run() {
            if (myDataSource.size() == 0) {
                addEmptyView(); // adding empty view instead of the RecyclerView
                return;
            }
            myDataSource.remove(position); //Remove the current content from the array
            myRVAdapter.notifyDataSetChanged(); //Refresh list
        }

    }, anim.getDuration());
}

第 2 步:

创建将删除所有RecyclerView 列表项的方法>> 在您的按钮单击回调中调用它。

boolean mStopHandler = false;

private void deleteAllItems() {

    final Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            
            if (myDataSource.size() == 0) {
                mStopHandler = true;
            }
            
            if (!mStopHandler) {
                View v = myRecyclerView.findViewHolderForAdapterPosition(0).itemView;
                deleteItem(v, 0);
            } else {
                handler.removeCallbacksAndMessages(null);
            }
            
            handler.postDelayed(this, 250);
        }
    };
    requireActivity().runOnUiThread(runnable);
}

同样重要的是要处理清单、活动部分中的配置更改,就像在清除回收站视图列表时配置更改一样,会引发异常

<activity
    android:name=".activities.MainActivity"
    android:configChanges="orientation|screenSize|keyboard"
    android:label="@string/app_name"
    ...
</activity>

【讨论】:

    【解决方案2】:

    使用RecyclerView.ItemAnimator

    https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ItemAnimator.html

    该类将在项目上发生的动画定义为更改 被制成适配器。 ItemAnimator 的子类可用于 为 ViewHolder 项上的操作实现自定义动画。

    您可以参考任何有关编写自定义ItemAnimator的教程:12

    【讨论】:

      【解决方案3】:

      您可以在每个循环中使用线程和延迟来逐一删除/恢复项目。以下是我的实现方式:

      MainActivity.java

      clearItemsView.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  final List<LineItem> lineItemsCopy = new ArrayList<>(lineItems);
                  new Thread(new Runnable() {
                      @Override
                      public void run() {
                          for (int i=0; i<lineItemsCopy.size(); i++) {
                              runOnUiThread(new Runnable() {
                                  @Override
                                  public void run() {
                                      salesOrderItemListAdapter.removeItem(0);
                                  }
                              });
                              try {
                                  Thread.sleep(500);
                              } catch (InterruptedException e) {
                                  e.printStackTrace();
                              }
                          }
                      }
                  }).start();
                  Snackbar snackbar = Snackbar.make(coordinatorLayout, getString(R.string.items_cleared_message), Snackbar.LENGTH_LONG)
                          .setAction(getString(R.string.label_undo), new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  new Thread(new Runnable() {
                                      @Override
                                      public void run() {
                                          for (int i=0; i<lineItemsCopy.size(); i++) {
                                              final int finalI = i;
                                              runOnUiThread(new Runnable() {
                                                  @Override
                                                  public void run() {
                                                      salesOrderItemListAdapter.restoreItem(lineItemsCopy.get(finalI), 0);
                                                  }
                                              });
                                              try {
                                                  Thread.sleep(500);
                                              } catch (InterruptedException e) {
                                                  e.printStackTrace();
                                              }
                                          }
                                      }
                                  }).start();
                              }
                          }).setActionTextColor(Color.YELLOW);
                  snackbar.show();
              }
          });
      

      RecyclerViewAdapter.java

          //Only remove & restore functions are shown    
          public void removeItem(int position) {
              lineItems.remove(position);
              notifyItemRemoved(position);
          }
      
          public void restoreItem(LineItem item, int position) {
              lineItems.add(position, item);
              notifyItemInserted(position);
          }
      

      【讨论】:

        猜你喜欢
        • 2020-07-27
        • 2017-09-06
        • 2019-04-12
        • 2015-01-27
        • 2021-01-24
        • 2020-05-06
        • 2016-11-12
        • 2019-07-18
        • 2016-10-03
        相关资源
        最近更新 更多