【问题标题】:How to know when user is done moving a RecyclerView item?如何知道用户何时完成移动 RecyclerView 项目?
【发布时间】:2021-01-01 00:40:22
【问题描述】:

当用户放下物品时,我需要执行一些操作。 ItemTouchHelper 似乎只调用 onMove 和 onMoved ,无论用户是否实际完成移动项目。 我如何知道用户何时完成移动项目?即,他们已经松开手指并将项目放回recyclerView?

【问题讨论】:

    标签: android android-recyclerview itemtouchhelper


    【解决方案1】:

    简单。只需覆盖onClearView()

    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {    //called when you dropped the item
        super.clearView(recyclerView, viewHolder);
    
        Toast.makeText(recyclerView.getContext(), "Item dropped on position: " + viewHolder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
    }
    

    【讨论】:

      【解决方案2】:

      您可以覆盖ItemTouchHelper.Callback 类的实现的onSelectedChanged() 回调,并使用可以是(ACTION_STATE_DRAGACTION_STATE_SWIPEACTION_STATE_IDLE)之一的开关情况检查actionState 值。

      ACTION_STATE_IDLE 是您要查找的内容,当滑动/拖动操作结束并且用户将手指离开屏幕时会触发它

      您可以使用布尔值来确定是滑动还是拖动,如下所示。

      private ItemTouchHelper createHelperCallback() {
          return new ItemTouchHelper(new ItemTouchHelper.Callback() {
      
              final boolean[] isSwiped = {false};
      
              @Override
              public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
                  return 0;
              }
      
              @Override
              public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                  return true;
              }
      
              @Override
              public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
              }
      
              @Override
              public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState) {
      
                  switch (actionState) {
      
                      case ItemTouchHelper.ACTION_STATE_DRAG:
                          // the user is dragging an item and didn't lift their finger off yet
                         isSwiped[0] = false;
                         break;
      
                      case ItemTouchHelper.ACTION_STATE_SWIPE:
                          // the user is swiping an item and didn't lift their finger off yet
                          isSwiped[0] = true;
                          break;
      
                      case ItemTouchHelper.ACTION_STATE_IDLE:
                          // the user just dropped the item (after dragging it), and lift their finger off.
      
                          if (isSwiped[0]) // The user used onSwiped()
                              Toast.makeText(MainActivity.this, "Swiping is over", Toast.LENGTH_SHORT).show();
                              
                          else // The user used onMove()
                              Toast.makeText(MainActivity.this, "Dragging & Dropping are over", Toast.LENGTH_SHORT).show();
                      
                  }
              }
      
          });
      }
      

      然后在你的 RecyclerView 上使用它

      createHelperCallback().attachToRecyclerView(recyclerView);
      

      预览

      【讨论】:

      • 原来 onClear() 是我让它工作所需要的,但这个答案对我也很有帮助,因为我也在试图了解如何利用这些动作状态。谢谢!
      • 关于这个答案的一些事情。因为您不更新onMove 中的数据,所以其他项目不会为拖动的项目腾出空间(您甚至可以在视频中看到)。此外,此答案不会跟踪 which item 实际移动到何处。您需要在onMove 中执行此操作。您还想在Toast 之后重置isSwiped/isMoved 状态,以防止多个 ACTION_STATE_IDLE 调用。最后isSwiped 不需要是布尔数组,只是布尔值
      【解决方案3】:

      您也可以覆盖getAnimationDuration(),它在onSelectedChanged() 之前调用(就在用户手指向上时),但您不能在此函数中访问viewHolder

      【讨论】:

      • 这似乎是一个实现细节,可能会在未来版本的 RV 库中更改,恕不另行通知。
      猜你喜欢
      • 2015-08-04
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多