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

首頁 > 系統(tǒng) > Android > 正文

android ItemTouchHelper實現(xiàn)可拖拽和側(cè)滑的列表的示例代碼

2019-12-12 01:09:34
字體:
供稿:網(wǎng)友

前言

話不多說,直接上圖:

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

實現(xiàn)功能:

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

實現(xiàn)基本功能

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

  1. 長按 item 實現(xiàn)上下拖拽
  2. 向右側(cè)滑刪除

布局文件

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

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 添加側(cè)滑刪除和拖拽的工具類。有了它,我們就可以很方便的實現(xiàn)上面的效果。 從構(gòu)造器: ItemTouchHelper(ItemTouchHelper.Callback callback) 可以看出,我們需要一個 ItemTouchHelper.Callback 去構(gòu)造 ItemTouchHelper 。

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

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

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

在寫 MyItemTouchHelperCallback 之前我們先創(chuàng)建一個 IItemTouchHelperAdapter 接口,讓 RecyclerViewAdapter 實現(xiàn)這個接口。用于 RecyclerViewAdapter 回調(diào)。

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

在 RecyclerViewAdapter 中實現(xiàn)剛剛繼承的兩個方法:

 @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;    //向右側(cè)滑,若有其他需求同理    int swipeFlags = ItemTouchHelper.RIGHT;    return makeMovementFlags(dragFlags, swipeFlags);  }  @Override  public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {    //通知Adapter更新數(shù)據(jù)和視圖    mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());    //若返回false則表示不支持上下拖拽    return true;  }  @Override  public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {    //通知Adapter更新數(shù)據(jù)和視圖    mAdapter.onItemDismiss(viewHolder.getAdapterPosition());  }    @Override  public boolean isItemViewSwipeEnabled() {    //是否可以左右側(cè)滑,默認返回true    return true;  }  @Override  public boolean isLongPressDragEnabled() {    //是否可以長按上下拖拽,默認返回false    return true;  }}

最后,在 Acivity 中將 ItemTouchHelper 和 RecyclerView 關(guān)聯(lián)起來

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

運行效果:

完善

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

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

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

首先修改 MyItemTouchHelperCallback 的 isLongPressDragEnabled()

 

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

其次新建一個OnStartDragListener接口,用于回調(diào)

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

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

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

在 RecyclerViewAdapter 的構(gòu)造方法中傳入 OnStartDragListener 的實例(即實現(xiàn)了該接口的Activity),給 item 左側(cè)的按鈕添加 事件監(jiān)聽

public class RecyclerViewAdapter extends    RecyclerView.Adapter<RecyclerViewAdapter.IItemViewHolder> implements IItemTouchHelperAdapter {  //構(gòu)造方法  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;      }    });  }    ...}

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

要實現(xiàn)這個效果,筆者使用 ItemTouchHelper.Callback 提供的兩個回調(diào)方法:

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

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

public interface IItemTouchHelperViewHolder {  /**   * item被選中,在側(cè)滑或拖拽過程中更新狀態(tài)   */  void onItemSelected();  /**   * item的拖拽或側(cè)滑結(jié)束,恢復默認的狀態(tài)   */  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() 來改變高度,但是行不通,后來查資料發(fā)現(xiàn) View 的Z軸陰影 Z = elevation + translationZ 其中:

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

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

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

 @Override  public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {    if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {      //不為空閑狀態(tài),即為拖拽或側(cè)滑狀態(tài)      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();    }  }

最后

這里是【源碼

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 奉新县| 毕节市| 泰州市| 丽江市| 周至县| 桑日县| 谷城县| 邯郸市| 万全县| 麟游县| 河津市| 波密县| 宁武县| 肥城市| 宁南县| 青海省| 防城港市| 美姑县| 定结县| 仙桃市| 永安市| 堆龙德庆县| 徐汇区| 大关县| 工布江达县| 涿州市| 松阳县| 万宁市| 清丰县| 雷州市| 安丘市| 武宁县| 弥勒县| 五华县| 云浮市| 涟水县| 通城县| 婺源县| 田东县| 南溪县| 定结县|