Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android使用RecycleView實現拖拽交換item位置

Android使用RecycleView實現拖拽交換item位置

編輯:關於Android編程

本文實例為大家分享了RecycleView實現拖拽交換item位置的具體代碼,供大家參考,具體內容如下

老規矩,先來一張效果圖:

相比起ListView而言,RecycleView實現拖拽交換位置的效果要簡單很多,因為通過SDK中的ItemTouchHelper工具類可以輕松的實現這種效果,並且一套代碼支持所有布局方式;而ListView的話則需要通過生成View的緩存鏡像設置到ImageView中,然後通過WindowManager來操作該ImageView,具體怎麼實現這裡就不展開講解了.回歸到ItemTouchHelper話題上,這個工具類我們需要關心的方法只有一個,即:

public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {}

通過名字也可以知道其作用就是和RecyclerView 建立關系.
而我們真正需要關心的地方就是ItemTouchHelper的內部類ItemTouchHelper.Callback,它是一個抽象類,需要我們去實現下面這幾個關鍵的抽象方法以及重寫幾個非抽象的方法:

//決定拖拽/滑動的方向
public abstract int getMovementFlags(RecyclerView recyclerView,
        ViewHolder viewHolder);

//和位置交換有關,可用於實現drag功能
public abstract boolean onMove(RecyclerView recyclerView,
        ViewHolder viewHolder, ViewHolder target);

//和滑動有關,可用於實現swipe功能
public abstract void onSwiped(ViewHolder viewHolder, int direction);

//是否長按啟用拖拽功能,默認是true
public boolean isLongPressDragEnabled() {return true;}

//是否支持滑動,默認true
public boolean isItemViewSwipeEnabled() {return true;}

//和目標View的狀態改變有關,例如drag,swipe,ide
public void onSelectedChanged(ViewHolder viewHolder, int actionState) {}

//和移除View的狀態有關,通常用於清除在onSelectedChanged,onChildDraw中對View設置的動畫
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {}

當創建完ItemTouchHelper.Callback的實現類,我這裡稱之為SimpleItemTouchHelperCallback後,還需要將數據的變化以及View的狀態通知到RecycleView的Adapter中,為了達到解耦的目的,通常可以通過定義接口來實現,在SimpleItemTouchHelperCallback的構造方法中傳入該解耦接口的引用,並讓RecycleView的Adapter實現該解耦的接口,這樣就實現了這2個類的通信問題了.

來看看我定義的解耦接口:

/**
 * 定義RecycleView的Adapter和SimpleItemTouchHelperCallback直接交互的接口方法
 * Created by mChenys on 2017/2/16.
 */
public interface ItemTouchHelperAdapter {

  //數據交換
  void onItemMove(RecyclerView.ViewHolder source, RecyclerView.ViewHolder target);

  //數據刪除
  void onItemDissmiss(RecyclerView.ViewHolder source);

  //drag或者swipe選中
  void onItemSelect(RecyclerView.ViewHolder source);

  //狀態清除
  void onItemClear(RecyclerView.ViewHolder source);
}

完整的SimpleItemTouchHelperCallback代碼如下:

/**
 * 處理RecycleView的選中,拖拽移動,拖拽刪除的實現類
 * Created by mChenys on 2017/2/16.
 */
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {

  private ItemTouchHelperAdapter mAdapter;

  public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) {
    mAdapter = adapter;
  }

  @Override
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    //int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; //允許上下的拖動
    //int dragFlags =ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //允許左右的拖動
    //int swipeFlags = ItemTouchHelper.LEFT; //只允許從右向左側滑
    //int swipeFlags = ItemTouchHelper.DOWN; //只允許從上向下側滑
    //一般使用makeMovementFlags(int,int)或makeFlag(int, int)來構造我們的返回值
    //makeMovementFlags(dragFlags, swipeFlags)

    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; //允許上下左右的拖動
    return makeMovementFlags(dragFlags, 0);
  }

  @Override
  public boolean isLongPressDragEnabled() {
    return true;//長按啟用拖拽
  }

  @Override
  public boolean isItemViewSwipeEnabled() {
    return false; //不啟用拖拽刪除
  }

  @Override
  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
    //通過接口傳遞拖拽交換數據的起始位置和目標位置的ViewHolder
    mAdapter.onItemMove(source, target);
    return true;
  }


  @Override
  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    //移動刪除回調,如果不用可以不用理
    // mAdapter.onItemDissmiss(viewHolder);
  }

  @Override
  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
    super.onSelectedChanged(viewHolder, actionState);
    if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
      //當滑動或者拖拽view的時候通過接口返回該ViewHolder
      mAdapter.onItemSelect(viewHolder);
    }
  }

  @Override
  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    super.clearView(recyclerView, viewHolder);
    if (!recyclerView.isComputingLayout()) {
      //當需要清除之前在onSelectedChanged或者onChildDraw,onChildDrawOver設置的狀態或者動畫時通過接口返回該ViewHolder
      mAdapter.onItemClear(viewHolder);
    }
  }
}

RecycleView.Adapter實現類代碼

/**
 * Created by mChenys on 2017/2/15.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements ItemTouchHelperAdapter {
  ...

  @Override
  public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
   ...
  }

  @Override
  public void onBindViewHolder(final MyAdapter.MyViewHolder holder, int position) {
    ...
  }

  @Override
  public int getItemCount() {
    //注意:這裡最少有一個,因為有多了一個添加按鈕
    return null == mData ? 1 : mData.size() + 1;
  }

  @Override
  public void onItemMove(RecyclerView.ViewHolder source,
   RecyclerView.ViewHolder target) {
    int fromPosition = source.getAdapterPosition();
    int toPosition = target.getAdapterPosition();
    if (fromPosition < mData.size() && toPosition < mData.size()) {
      //交換數據位置
      Collections.swap(mData, fromPosition, toPosition);
      //刷新位置交換
      notifyItemMoved(fromPosition, toPosition);
    }
    //移動過程中移除view的放大效果
    onItemClear(source);
  }

  @Override
  public void onItemDissmiss(RecyclerView.ViewHolder source) {

    int position = source.getAdapterPosition();
    mData.remove(position); //移除數據
    notifyItemRemoved(position);//刷新數據移除
  }

  @Override
  public void onItemSelect(RecyclerView.ViewHolder viewHolder) {

    //當拖拽選中時放大選中的view
    viewHolder.itemView.setScaleX(1.2f);
    viewHolder.itemView.setScaleY(1.2f);
  }

  @Override
  public void onItemClear(RecyclerView.ViewHolder viewHolder) {

    //拖拽結束後恢復view的狀態
    viewHolder.itemView.setScaleX(1.0f);
    viewHolder.itemView.setScaleY(1.0f);
  }

  public class MyViewHolder extends RecyclerView.ViewHolder {
   ...

    public MyViewHolder(View itemView) {
      super(itemView);
     ...
    }
  }

}

MainActivity的使用方式

/**
 * Created by mChenys on 2017/2/16.
 */
public class MainActivity extends AppCompatActivity {
  ...
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    mRecyclerView = (RecyclerView) findViewById(R.id.recycleView);
    //創建adapter
    MyAdapter myAdapter = new MyAdapter(this, mData);
    //設置默認的布局方式
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
    //設置adapter
    mRecyclerView.setAdapter(myAdapter);
    //創建SimpleItemTouchHelperCallback
    ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(myAdapter);
    //用Callback構造ItemtouchHelper
    ItemTouchHelper touchHelper = new ItemTouchHelper(callback); 
    //調用ItemTouchHelper的attachToRecyclerView方法建立聯系
    touchHelper.attachToRecyclerView(mRecyclerView);
  }



  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    ...
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    ...
    return super.onOptionsItemSelected(item);
  }

}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved