国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android ItemTouchHelper實現可拖拽和側滑的列表的示例代碼

2019-10-22 18:14:49
字體:
來源:轉載
供稿:網友

前言

話不多說,直接上圖:

ItemTouchHelper,android,拖拽,側滑

筆者使用 RecyclerView 的 ItemTouchHelper 來實現這個效果,過程非常簡單。為了學習,這里順便實現了一下側滑刪除。

實現功能:

  1. 按住 item 左側的按鈕可以上下拖動 item
  2. 向右側滑刪除 item
  3. item 拖動或側滑時有陰影效果

實現基本功能

循序漸進學習,這里我們先實現基本的功能:

  1. 長按 item 實現上下拖拽
  2. 向右側滑刪除

布局文件

很簡單,不多說,直接上代碼:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent">  <android.support.v7.widget.RecyclerView    android:layout_width="match_parent"    android:layout_height="match_parent"    android:id="@+id/main_recyclerView"    android:scrollbars="none"    android:background="#F2F8FC">  </android.support.v7.widget.RecyclerView></LinearLayout>

item_list.xml

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:app="http://schemas.android.com/apk/res-auto"  android:layout_width="match_parent"  android:layout_height="60dp"  android:background="#ffffff">    <ImageView    android:id="@+id/item_list_menu_imageView"    android:layout_width="30dp"    android:layout_height="25dp"    android:layout_marginBottom="8dp"    android:layout_marginStart="15dp"    android:layout_marginTop="8dp"    android:src="@drawable/imageview_menu"    app:layout_constraintBottom_toBottomOf="parent"    app:layout_constraintStart_toStartOf="parent"    app:layout_constraintTop_toTopOf="parent" />    <TextView    android:id="@+id/item_list_text_textView"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginBottom="8dp"    android:layout_marginStart="15dp"    android:layout_marginTop="8dp"    android:textColor="#000000"    android:textSize="18sp"    app:layout_constraintBottom_toBottomOf="parent"    app:layout_constraintStart_toEndOf="@+id/item_list_menu_imageView"    app:layout_constraintTop_toTopOf="parent"/>  <android.support.v7.widget.SwitchCompat    android:id="@+id/item_list_switchCompat"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginBottom="8dp"    android:layout_marginEnd="15dp"    android:layout_marginTop="8dp"    app:layout_constraintBottom_toBottomOf="parent"    app:layout_constraintEnd_toEndOf="parent"    app:layout_constraintTop_toTopOf="parent"    />  </android.support.constraint.ConstraintLayout>

ItemTouchHelper

官方的API解釋:

This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

這是一個給 RecyclerView 添加側滑刪除和拖拽的工具類。有了它,我們就可以很方便的實現上面的效果。 從構造器: ItemTouchHelper(ItemTouchHelper.Callback callback) 可以看出,我們需要一個 ItemTouchHelper.Callback 去構造 ItemTouchHelper 。

ItemTouchHelper.Callback 官方提供了一個實現類 ItemTouchHelper.SimpleCallback() ,它的使用很簡單,但為了得到更高的定制性,這里我們不使用它,有興趣的朋友可以去嘗試一下。

新建一個 MyItemTouchHelperCallback 類繼承 ItemTouchHelper.Callback ,這里我們關注它其中的三個方法:

  1. getMovementFlags() 定義 item 的可以拖拽和滑動的方向。
  2. onMove() 當 item 想要上下拖拽時會調用此方法。
  3. onSwiped 當 item 想要左右側滑時會調用此方法。

在寫 MyItemTouchHelperCallback 之前我們先創建一個 IItemTouchHelperAdapter 接口,讓 RecyclerViewAdapter 實現這個接口。用于 RecyclerViewAdapter 回調。

public interface IItemTouchHelperAdapter {  /**   * 當item被移動時調用   *   * @param fromPosition 被操作的item的起點   * @param toPosition  被操作的item的終點   */  void onItemMove(int fromPosition, int toPosition);  /**   * 當item被側滑時調用   *   * @param position 被側滑的item的position   */  void onItemDismiss(int position);}

在 RecyclerViewAdapter 中實現剛剛繼承的兩個方法:

 @Override  public void onItemMove(int fromPosition, int toPosition) {    Collections.swap(mList, fromPosition, toPosition);    notifyItemMoved(fromPosition, toPosition);  }  @Override  public void onItemDismiss(int position) {    mList.remove(position);    notifyItemRemoved(position);  }

之后我們就可以開始編寫 MyItemTouchHelperCallback ,注釋很清楚,就不多說了。

public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {  private IItemTouchHelperAdapter mAdapter;  public MyItemTouchHelperCallback(IItemTouchHelperAdapter mAdapter) {    this.mAdapter = mAdapter;  }  @Override  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {    //上下拖拽,若有其他需求同理    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;    //向右側滑,若有其他需求同理    int swipeFlags = ItemTouchHelper.RIGHT;    return makeMovementFlags(dragFlags, swipeFlags);  }  @Override  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {    //通知Adapter更新數據和視圖    mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());    //若返回false則表示不支持上下拖拽    return true;  }  @Override  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {    //通知Adapter更新數據和視圖    mAdapter.onItemDismiss(viewHolder.getAdapterPosition());  }    @Override  public boolean isItemViewSwipeEnabled() {    //是否可以左右側滑,默認返回true    return true;  }  @Override  public boolean isLongPressDragEnabled() {    //是否可以長按上下拖拽,默認返回false    return true;  }}

最后,在 Acivity 中將 ItemTouchHelper 和 RecyclerView 關聯起來

mItemTouchHelper = new ItemTouchHelper(new MyItemTouchHelperCallback(adapter));mItemTouchHelper.attachToRecyclerView(recyclerView);

運行效果:

ItemTouchHelper,android,拖拽,側滑

完善

我們實現的的基本效果與文章開頭給出的效果還是有一點差距的,還需要實現的效果:

  1. 通過按住 item 左邊按鈕才能上下拖拽。
  2. 側滑或拖拽時被操作的 item Z軸高度增加,有明顯的陰影。

通過按住 item 左邊按鈕才能上下拖拽

首先修改 MyItemTouchHelperCallback 的 isLongPressDragEnabled()

 

@Override  public boolean isLongPressDragEnabled() {    //禁止長按item可以上下拖拽,因為我們要自定義開啟拖拽的時機    return false;  }

其次新建一個OnStartDragListener接口,用于回調

public interface OnStartDragListener {  /**   * 當View需要拖拽時回調   *   * @param viewHolder The holder of view to drag   */  void onStartDrag(RecyclerView.ViewHolder viewHolder);}

讓 Activity 繼承這個類,實現 onStartDrag() 方法

@Override  public void onStartDrag(RecyclerView.ViewHolder viewHolder) {    //通知ItemTouchHelper開始拖拽    mItemTouchHelper.startDrag(viewHolder);  }

在 RecyclerViewAdapter 的構造方法中傳入 OnStartDragListener 的實例(即實現了該接口的Activity),給 item 左側的按鈕添加 事件監聽

public class RecyclerViewAdapter extends    RecyclerView.Adapter<RecyclerViewAdapter.IItemViewHolder> implements IItemTouchHelperAdapter {  //構造方法  public RecyclerViewAdapter(List<ItemEntity> list, OnStartDragListener mDragListener) {    mList = list;    this.mDragListener = mDragListener;  }    ...     @Override  public void onBindViewHolder(final IItemViewHolder holder, @SuppressLint("RecyclerView") final int position) {    ...    holder.menu.setOnTouchListener(new View.OnTouchListener() {      @Override      public boolean onTouch(View view, MotionEvent motionEvent) {        if (motionEvent.getAction()            == MotionEvent.ACTION_DOWN) {          //通知ItemTouchHelper開始拖拽            mDragListener.onStartDrag(holder);        }        return false;      }    });  }    ...}

側滑或拖拽時被操作的 item Z軸高度增加,有明顯的陰影

要實現這個效果,筆者使用 ItemTouchHelper.Callback 提供的兩個回調方法:

  1. onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) :當 ViewHolder (即 item )滑動或拖動時被調用。
  2. clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) :當 ViewHolder 滑動和拖拽結束時被調用

首先新建一個 IItemTouchHelperViewHolder 接口用于回調,讓 RecyclerViewAdapter 的 ViewHolder 繼承它。

public interface IItemTouchHelperViewHolder {  /**   * item被選中,在側滑或拖拽過程中更新狀態   */  void onItemSelected();  /**   * item的拖拽或側滑結束,恢復默認的狀態   */  void onItemClear();}

然后讓ViewHolder重寫上述的兩個方法:

 class ItemViewHolder extends RecyclerView.ViewHolder implements IItemTouchHelperViewHolder {    private TextView text;    private ImageView menu;    private SwitchCompat switchCompat;    ItemViewHolder(View itemView) {      super(itemView);      text = itemView.findViewById(R.id.item_list_text_textView);      menu = itemView.findViewById(R.id.item_list_menu_imageView);      switchCompat = itemView.findViewById(R.id.item_list_switchCompat);    }    @Override    public void onItemSelected() {      itemView.setTranslationZ(10);    }    @Override    public void onItemClear() {      itemView.setTranslationZ(0);    }}

這里通過 setTranslationZ() 來改變 itemView 的高度。

之前筆者嘗試通過 setElevation() 來改變高度,但是行不通,后來查資料發現 View 的Z軸陰影 Z = elevation + translationZ 其中:

  1. elevation 是靜態值,是 View 在Z軸上的初始值
  2. translationZ 是動態值,是Z上的偏移變化

所以我們這里應該使用 setTranslationZ() 來改變 View 的Z軸高度而不是使用 setElevation() ,讀者們可以自行嘗試一下。

最后修改 MyItemTouchHelperCallback ,重寫上述的兩個方法,過程很簡單,直接看代碼:

 @Override  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {    if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {      //不為空閑狀態,即為拖拽或側滑狀態      if (viewHolder instanceof IItemTouchHelperViewHolder) {        IItemTouchHelperViewHolder itemTouchHelperViewHolder =            (IItemTouchHelperViewHolder) viewHolder;        itemTouchHelperViewHolder.onItemSelected();      }    }    super.onSelectedChanged(viewHolder, actionState);  }  @Override  public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {    super.clearView(recyclerView, viewHolder);    if (viewHolder instanceof IItemTouchHelperViewHolder) {      IItemTouchHelperViewHolder itemTouchHelperViewHolder =          (IItemTouchHelperViewHolder) viewHolder;      itemTouchHelperViewHolder.onItemClear();    }  }

最后

這里是【源碼

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


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 茂名市| 修水县| 元阳县| 三原县| 罗定市| 宿州市| 瓦房店市| 犍为县| 杨浦区| 邛崃市| 哈巴河县| 阿巴嘎旗| 西盟| 永登县| 灵武市| 岐山县| 旺苍县| 兰溪市| 定南县| 彰武县| 和静县| 南皮县| 金山区| 建瓯市| 璧山县| 佛教| 和静县| 泸水县| 乌苏市| 肇庆市| 乾安县| 保山市| 双流县| 闽侯县| 丰镇市| 赣州市| 芜湖县| 文登市| 六枝特区| 梨树县| 彰武县|