欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android RecyclerView實現(xiàn)條目Item拖拽排序與滑動刪除

 更新時間:2017年03月01日 15:05:05   作者:嚴(yán)振杰  
本篇文章主要介紹了android RecyclerView實現(xiàn)條目Item拖拽排序與滑動刪除,具有一定的參考價值,感興趣的小伙伴們可以參考一下。

效果演示

需求和技術(shù)分析

  • RecyclerView Item拖拽排序::長按RecyclerView的Item或者觸摸Item的某個按鈕。
  • RecyclerView Item滑動刪除:RecyclerView Item滑動刪除:RecyclerView的Item滑動刪除。

實現(xiàn)方案與技術(shù)

利用ItemTouchHelper綁定RecyclerView、ItemTouchHelper.Callback來實現(xiàn)UI更新,并且實現(xiàn)動態(tài)控制是否開啟拖拽功能和滑動刪除功能。

實現(xiàn)步驟

  • 繼承抽象類ItemTouchHelper,并在構(gòu)造方法傳入實現(xiàn)的ItemTouchHelper.Callback。
  • recyclerView綁定ItemTouchHelper:itemTouchHelper.attachToRecyclerView(recyclerView)。
  • 自定義ItemTouchHelper.Callback的實現(xiàn)接口OnItemTouchCallbackListener,由外部更新RecyclerView的Item。

幾個主要的布局

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:orientation="vertical">

  <android.support.v7.widget.RecyclerView
    android:id="@+id/rv_main"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</LinearLayout>

這個沒啥好說的了吧,就是一個RecyclerView啦。

接下來是RecyclerView的Item的布局item.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="?android:listPreferredItemHeight"
  android:background="?selectableItemBackground">

  <ImageView
    android:id="@+id/iv_touch"
    style="@style/ItemStyle"
    android:layout_height="match_parent"
    android:layout_alignParentEnd="true"
    android:layout_alignParentRight="true"
    android:src="@android:drawable/alert_dark_frame" />

  <CheckBox
    android:id="@+id/cb_item_check"
    style="@style/ItemStyle"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

  <TextView
    android:id="@+id/tv_name"
    style="@style/ItemStyle"
    android:layout_toEndOf="@id/cb_item_check"
    android:layout_toRightOf="@id/cb_item_check" />

  <TextView
    android:id="@+id/tv_sex"
    style="@style/ItemStyle"
    android:layout_marginLeft="@dimen/dp_10"
    android:layout_marginStart="@dimen/dp_10"
    android:layout_toEndOf="@id/tv_name"
    android:layout_toRightOf="@id/tv_name" />

</RelativeLayout>

這個也不用解釋了,到時候下載看源碼,就是普通item,展示數(shù)據(jù)而已。

實現(xiàn)自己的DefaultItemTouchHelper:繼承ItemTouchHelper

public class DefaultItemTouchHelper extends ItemTouchHelper {
  public DefaultItemTouchHelper(ItemTouchHelp.Callback callback) {
    super(callback);
  }
}

好嘛,這個太簡單了,基本上一行代碼都不用寫。但是這里需要一個ItemTouchHelp.Callback啊,所以我們還是要實現(xiàn)一個ItemTouchHelp.Callback,客觀且看下文分解。

實現(xiàn)自己的ItemTouchHelper.Callback:繼承ItemTouchHelper.Callback

這里是全文最重要的部分啦,要認(rèn)真點看噢,先上代碼,后解釋,其他看注釋和視頻。

public class DefaultItemTouchHelpCallback extends ItemTouchHelper.Callback {

  /**
   * Item操作的回調(diào)
   */
  private OnItemTouchCallbackListener onItemTouchCallbackListener;

  /**
   * 是否可以拖拽
   */
  private boolean isCanDrag = false;
  /**
   * 是否可以被滑動
   */
  private boolean isCanSwipe = false;

  public DefaultItemTouchHelpCallback(OnItemTouchCallbackListener onItemTouchCallbackListener) {
    this.onItemTouchCallbackListener = onItemTouchCallbackListener;
  }

  /**
   * 設(shè)置Item操作的回調(diào),去更新UI和數(shù)據(jù)源
   *
   * @param onItemTouchCallbackListener
   */
  public void setOnItemTouchCallbackListener(OnItemTouchCallbackListener onItemTouchCallbackListener) {
    this.onItemTouchCallbackListener = onItemTouchCallbackListener;
  }

  /**
   * 設(shè)置是否可以被拖拽
   *
   * @param canDrag 是true,否false
   */
  public void setDragEnable(boolean canDrag) {
    isCanDrag = canDrag;
  }

  /**
   * 設(shè)置是否可以被滑動
   *
   * @param canSwipe 是true,否false
   */
  public void setSwipeEnable(boolean canSwipe) {
    isCanSwipe = canSwipe;
  }

  /**
   * 當(dāng)Item被長按的時候是否可以被拖拽
   *
   * @return
   */
  @Override
  public boolean isLongPressDragEnabled() {
    return isCanDrag;
  }

  /**
   * Item是否可以被滑動(H:左右滑動,V:上下滑動)
   *
   * @return
   */
  @Override
  public boolean isItemViewSwipeEnabled() {
    return isCanSwipe;
  }

  /**
   * 當(dāng)用戶拖拽或者滑動Item的時候需要我們告訴系統(tǒng)滑動或者拖拽的方向
   *
   * @param recyclerView
   * @param viewHolder
   * @return
   */
  @Override
  public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
    if (layoutManager instanceof GridLayoutManager) {// GridLayoutManager
      // flag如果值是0,相當(dāng)于這個功能被關(guān)閉
      int dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.UP | ItemTouchHelper.DOWN;
      int swipeFlag = 0;
      // create make
      return makeMovementFlags(dragFlag, swipeFlag);
    } else if (layoutManager instanceof LinearLayoutManager) {// linearLayoutManager
      LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
      int orientation = linearLayoutManager.getOrientation();

      int dragFlag = 0;
      int swipeFlag = 0;

      // 為了方便理解,相當(dāng)于分為橫著的ListView和豎著的ListView
      if (orientation == LinearLayoutManager.HORIZONTAL) {// 如果是橫向的布局
        swipeFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        dragFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
      } else if (orientation == LinearLayoutManager.VERTICAL) {// 如果是豎向的布局,相當(dāng)于ListView
        dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
      }
      return makeMovementFlags(dragFlag, swipeFlag);
    }
    return 0;
  }

  /**
   * 當(dāng)Item被拖拽的時候被回調(diào)
   *
   * @param recyclerView   recyclerView
   * @param srcViewHolder  拖拽的ViewHolder
   * @param targetViewHolder 目的地的viewHolder
   * @return
   */
  @Override
  public boolean onMove(RecyclerView recyclerView, ViewHolder srcViewHolder, ViewHolder targetViewHolder) {
    if (onItemTouchCallbackListener != null) {
      return onItemTouchCallbackListener.onMove(srcViewHolder.getAdapterPosition(), targetViewHolder.getAdapterPosition());
    }
    return false;
  }

  @Override
  public void onSwiped(ViewHolder viewHolder, int direction) {
    if (onItemTouchCallbackListener != null) {
      onItemTouchCallbackListener.onSwiped(viewHolder.getAdapterPosition());
    }
  }

  public interface OnItemTouchCallbackListener {
    /**
     * 當(dāng)某個Item被滑動刪除的時候
     *
     * @param adapterPosition item的position
     */
    void onSwiped(int adapterPosition);

    /**
     * 當(dāng)兩個Item位置互換的時候被回調(diào)
     *
     * @param srcPosition  拖拽的item的position
     * @param targetPosition 目的地的Item的position
     * @return 開發(fā)者處理了操作應(yīng)該返回true,開發(fā)者沒有處理就返回false
     */
    boolean onMove(int srcPosition, int targetPosition);
  }
}

好,其實上面最重要的就是五個方法:

/**
 * 是否可以長按拖拽排序。
 */
@Override
public boolean isLongPressDragEnabled() {}
/**
 * Item是否可以被滑動(H:左右滑動,V:上下滑動)
 */
@Override
public boolean isItemViewSwipeEnabled() {}
/**
 * 當(dāng)用戶拖拽或者滑動Item的時候需要我們告訴系統(tǒng)滑動或者拖拽的方向
 */
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {}
/**
 * 當(dāng)Item被拖拽的時候被回調(diào)
 */
@Override
public boolean onMove(RecyclerView r, ViewHolder rholer, ViewHolder tholder) {}

/**
 * 當(dāng)View被滑動刪除的時候
 */
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {}



isItemViewSwipeEnabled()返回值是否可以拖拽排序,true可以,false不可以,isItemViewSwipeEnabled()是否可以滑動刪除,true可以,false不可以;這兩個方法都是配置是否可以操作的。我們上面的代碼中返回了一個成員變量值,并且這個值通過外部可以修改,所以提供了外部控制的方法。

onMove()當(dāng)Item被拖拽排序移動到另一個Item的位置的時候被回調(diào),onSwiped()當(dāng)Item被滑動刪除到不見;這兩個方法是當(dāng)用戶操作了,來回調(diào)我們,我們就該去更新UI了。這里我們提供了一個Listener去通知外部,并且返回出去了必要的值,來降低代碼耦合度。

getMovementFlags()說明一:是當(dāng)用戶拖拽或者滑動Item的時候需要我們告訴系統(tǒng)滑動或者拖拽的方向,那我們又知道支持拖拽和滑動刪除的無非就是LinearLayoutManager和GridLayoutManager了,相當(dāng)于我們老早的時候用的ListView和GridView了。所以我們根據(jù)布局管理器的不同做了響應(yīng)的區(qū)分。

getMovementFlags()說明二:其他都好理解,就是這里的return makeMovementFlags(dragFlag, swipeFlag);這句話是最終的返回值,也就是它決定了我們的拖拽或者滑動的方法。第一個參數(shù)是拖拽flag,第二個是滑動的flag。

重新定義DefaultItemTouchHelper

我們記得上面定義了一個DefaultItemTouchHelper,它的構(gòu)造中需要傳一個ItemTouchHelper.Callback,既然我們實現(xiàn)禮了,我們再把DefaultItemTouchHelper做個封裝,使使用者更傻瓜式的調(diào)用。

public class DefaultItemTouchHelper extends YolandaItemTouchHelper {

  private DefaultItemTouchHelpCallback itemTouchHelpCallback;

  public DefaultItemTouchHelper(DefaultItemTouchHelpCallback.OnItemTouchCallbackListener onItemTouchCallbackListener) {
    super(new DefaultItemTouchHelpCallback(onItemTouchCallbackListener));
    itemTouchHelpCallback = (DefaultItemTouchHelpCallback) getCallback();
  }

  /**
   * 設(shè)置是否可以被拖拽
   *
   * @param canDrag 是true,否false
   */
  public void setDragEnable(boolean canDrag) {
    itemTouchHelpCallback.setDragEnable(canDrag);
  }

  /**
   * 設(shè)置是否可以被滑動
   *
   * @param canSwipe 是true,否false
   */
  public void setSwipeEnable(boolean canSwipe) {
    itemTouchHelpCallback.setSwipeEnable(canSwipe);
  }
}

現(xiàn)在我們看到已經(jīng)不需要傳ItemTouchHelper.Callback給ItemTouchHelper了,只需要傳我們在DefaultItemTouchHelpCallback中定義好的OnItemTouchCallbackListener就好了,而且提供了設(shè)置是否可以滑動和是否可以拖拽的方法,而OnItemTouchCallbackListener只是通知外部滑動了、刪除了,你去更新UI吧。

這里可以有的同學(xué)會有疑問,上面原來不是繼承ItemTouchHelper嗎?這里咋就變成了YolandaItemTouchHelper了呢?因為我們看到這里多了一句itemTouchHelpCallback = getCallback();,這個getCallback();這個方法是沒有的,是我們在YolandaItemTouchHelper中自定義的,因為我們想在DefaultItemTouchHelper中提供外部設(shè)置是否可以拖拽和滑動刪除的方法,就得拿到這個Callback,所以我看了下源碼,我們在ItemTouchHelper構(gòu)造中把Callback穿進去,它保存的時候一個package級別的成員變量,所以我在Android.support.v7.widget.helper包下新建了一個YolandaItemTouchHelper類:

public class YolandaItemTouchHelper extends ItemTouchHelper {
  public YolandaItemTouchHelper(Callback callback) {
    super(callback);
  }

  public Callback getCallback() {
    return mCallback;
  }
}

如何投入使用

好扯淡也扯完了,封裝也封裝完了,那么接下來就來在Activity中使用下咯:

recyclerView綁定ItemTouchHelper

沒啥好說的用itemTouchHelper.attachToRecyclerView(recyclerView)綁定recyclerView和ItemTouchHelper,并且只是允許拖拽和滑動刪除Item:

DefaultItemTouchHelper itemTouchHelper = new DefaultItemTouchHelper(onItemTouchCallbackListener);
itemTouchHelper.attachToRecyclerView(recyclerView);
itemTouchHelper.setDragEnable(true);
itemTouchHelper.setSwipeEnable(true);

看到上面還缺少一個onItemTouchCallbackListener吧,這個也比較重要。

使用Callback自定義的OnItemTouchCallbackListener刷新UI

我們在自定義Callback的時候不是在onMove()和onSwiped()方法中回調(diào)OnItemTouchCallbackListener去更新UI嗎?這里就是OnItemTouchCallbackListener如何更新UI的操作了,完成這個操作,那么我們的目的就達(dá)到了:

private DefaultItemTouchHelpCallback.OnItemTouchCallbackListener onItemTouchCallbackListener = new DefaultItemTouchHelpCallback.OnItemTouchCallbackListener() {
  @Override
  public void onSwiped(int adapterPosition) {
    // 滑動刪除的時候,從數(shù)據(jù)源移除,并刷新這個Item。
    if (userInfoList != null) {
      userInfoList.remove(adapterPosition);
      mainAdapter.notifyItemRemoved(adapterPosition);
    }
  }

  @Override
  public boolean onMove(int srcPosition, int targetPosition) {
    if (userInfoList != null) {
      // 更換數(shù)據(jù)源中的數(shù)據(jù)Item的位置
      Collections.swap(userInfoList, srcPosition, targetPosition);
      // 更新UI中的Item的位置,主要是給用戶看到交互效果
      mainAdapter.notifyItemMoved(srcPosition, targetPosition);
      return true;
    }
    return false;
  }
};

到這里就結(jié)束了,不信你去試試,源碼傳送門

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android Bluetooth藍(lán)牙技術(shù)初體驗

    Android Bluetooth藍(lán)牙技術(shù)初體驗

    這篇文章主要介紹了Android Bluetooth藍(lán)牙技術(shù)初體驗的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 詳解Android 進程

    詳解Android 進程

    這篇文章主要介紹了Android 進程的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Android開發(fā),感興趣的朋友可以了解下
    2020-08-08
  • Android實現(xiàn)手機震動效果

    Android實現(xiàn)手機震動效果

    這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)手機震動效果的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Android Parcelable接口使用方法詳解

    Android Parcelable接口使用方法詳解

    這篇文章主要介紹了 Android Parcelable接口使用方法詳解的相關(guān)資料,實現(xiàn)Parcelable就是為了進行序列化,需要的朋友可以參考下
    2017-08-08
  • 解決android studio中使用monitor工具無法打開data文件夾問題

    解決android studio中使用monitor工具無法打開data文件夾問題

    這篇文章主要介紹了解決android studio中使用monitor工具無法打開data文件夾問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • 淺談Gradle 常用配置總結(jié)

    淺談Gradle 常用配置總結(jié)

    這篇文章主要介紹了淺談Gradle 常用配置總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Android桌面組件App Widget完整案例

    Android桌面組件App Widget完整案例

    這篇文章主要介紹了Android桌面組件App Widget完整案例,較為詳細(xì)的分析了Android桌面組件App Widget的功能、定義及實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • Android滑動優(yōu)化高仿QQ6.0側(cè)滑菜單(滑動優(yōu)化)

    Android滑動優(yōu)化高仿QQ6.0側(cè)滑菜單(滑動優(yōu)化)

    之前的實現(xiàn)只是簡單的可以顯示和隱藏左側(cè)的菜單,但是特別生硬,而且沒有任何平滑的趨勢,那么今天就來優(yōu)化一下吧,加上平滑效果,而且可以根據(jù)手勢滑動的方向來判斷是否是顯示和隱藏
    2016-02-02
  • Android中使用Vectors(2)繪制優(yōu)美的路徑動畫

    Android中使用Vectors(2)繪制優(yōu)美的路徑動畫

    這篇文章主要介紹了Android中使用Vectors(2)繪制優(yōu)美的路徑動畫的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Android?換膚實現(xiàn)指南demo及案例解析

    Android?換膚實現(xiàn)指南demo及案例解析

    這篇文章主要為大家介紹了Android換膚指南demo及案例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06

最新評論