前言
從Android 5.0開始,谷歌推出了新的控件RecyclerView,相對于早它之前的ListView,優點多多,功能強大,也給我們的開發著提供了極大的便利,今天自己學習一下RecyclerView輕松實現滑動刪除及拖拽的效果。
如下圖。

相信研究過RecyclerView的同學,應該很清楚該怎么實現這樣的效果,若是用ListView,這樣的效果實現起來可能就有點麻煩,但是在強大的RecyclerView面前這樣的的效果只需很少的代碼,因為谷歌給我們提供了強大的工具類ItemTouchHelper,它已經處理了關于RecyclerView拖動和滑動的實現,并且我們可以在其中實現我們自己的動畫,以及定制我們想要的效果。
ItemTouchHelper.Callback
ItemTouchHelper.Callback有幾個重要的抽象方法,我們繼承該抽象類,并重寫抽象方法。它是我們實現滑動和拖拽重要的回調。
int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
該方法返回一個整數,用來指定拖拽和滑動在哪個方向是被允許的。在其中使用makeMovementFlags(int dragFlags, int swipeFlags)返回,該方法第一個參數用來指定拖動,第二個參數用來指定滑動。對于方向參數有6種
ItemTouchHelper.UP //滑動拖拽向上方向ItemTouchHelper.DOWN//向下ItemTouchHelper.LEFT//向左ItemTouchHelper.RIGHT//向右ItemTouchHelper.START//依賴布局方向的水平開始方向ItemTouchHelper.END//依賴布局方向的水平結束方向
boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
onMove方法是拖拽的回調,參數viewHolder是拖動的Item,target是拖動的目標位置的Item,該方法如果返回true表示切換了位置,反之返回false。
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction)
onSwiped方法為Item滑動回調,viewHolder為滑動的item,direction為滑動的方向。
上面三個方法是必須重寫的方法,當然還有其它一些可供選擇的方法。
/** * Item是否支持長按拖動 * * @return * true 支持長按操作 * false 不支持長按操作 */boolean isLongPressDragEnabled() /** * Item是否支持滑動 * * @return * true 支持滑動操作 * false 不支持滑動操作 */boolean isItemViewSwipeEnabled() /** * 移動過程中繪制Item * * @param c * @param recyclerView * @param viewHolder * @param dX * X軸移動的距離 * @param dY * Y軸移動的距離 * @param actionState * 當前Item的狀態 * @param isCurrentlyActive * 如果當前被用戶操作為true,反之為false */onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
需要注意的是,如果我們想實現拖動或者滑動必須將上面是否支持拖動或者滑動的方法返回true,否則onMove或者onSwiped方法不會執行。
功能實現
adapter=new CustomAdapter(getActivity(),strings); recycleview.setAdapter(adapter); ItemTouchHelper.Callback callback=new RecycleItemTouchHelper(adapter); ItemTouchHelper itemTouchHelper=new ItemTouchHelper(callback); itemTouchHelper.attachToRecyclerView(recycleview);
對于ItemTouchHelper 構造方法接收一個ItemTouchHelper.Callback參數,而這個Callback就是我們在在上述講到的工具類,初始化ItemTouchHelper 后通過其attachToRecyclerView(@Nullable RecyclerView recyclerView)方法將我們實現的ItemTouchHelper.Callback和RecyclerView關聯,最終達到我們的效果,代碼看起來是不是很簡單,接下來我們看下我們自定義的Callback。
package com.example.xh.adapter;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Rect;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.helper.ItemTouchHelper;import android.util.Log;import android.view.View;import com.example.xh.R;import com.example.xh.utils.MyApplication;/** * Created by xiehui on 2017/2/23. */public class RecycleItemTouchHelper extends ItemTouchHelper.Callback{ private static final String TAG ="RecycleItemTouchHelper" ; private final ItemTouchHelperCallback helperCallback; public RecycleItemTouchHelper(ItemTouchHelperCallback helperCallback) { this.helperCallback = helperCallback; } /** * 設置滑動類型標記 * * @param recyclerView * @param viewHolder * @return * 返回一個整數類型的標識,用于判斷Item那種移動行為是允許的 */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { Log.e(TAG, "getMovementFlags: " ); //START 右向左 END左向右 LEFT 向左 RIGHT向右 UP向上 //如果某個值傳0,表示不觸發該操作,次數設置支持上下拖拽,支持向右滑動 return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper.END ); } /** * Item是否支持長按拖動 * * @return * true 支持長按操作 * false 不支持長按操作 */ @Override public boolean isLongPressDragEnabled() { return super.isLongPressDragEnabled(); } /** * Item是否支持滑動 * * @return * true 支持滑動操作 * false 不支持滑動操作 */ @Override public boolean isItemViewSwipeEnabled() { return super.isItemViewSwipeEnabled(); } /** * 拖拽切換Item的回調 * * @param recyclerView * @param viewHolder * @param target * @return * 如果Item切換了位置,返回true;反之,返回false */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { Log.e(TAG, "onMove: " ); helperCallback.onMove(viewHolder.getAdapterPosition(),target.getAdapterPosition()); return true; } /** * 滑動Item * * @param viewHolder * @param direction * Item滑動的方向 */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { Log.e(TAG, "onSwiped: "); helperCallback.onItemDelete(viewHolder.getAdapterPosition()); } /** * Item被選中時候回調 * * @param viewHolder * @param actionState * 當前Item的狀態 * ItemTouchHelper.ACTION_STATE_IDLE 閑置狀態 * ItemTouchHelper.ACTION_STATE_SWIPE 滑動中狀態 * ItemTouchHelper#ACTION_STATE_DRAG 拖拽中狀態 */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); } public interface ItemTouchHelperCallback{ void onItemDelete(int positon); void onMove(int fromPosition,int toPosition); }}在默認情況下是支持拖動和滑動的,也就是isLongPressDragEnabled()和isItemViewSwipeEnabled()是返回true的。在該類中我們創建了一個接口ItemTouchHelperCallback并創建兩個抽象方法,分別表示拖拽和滑動。在onMove方法中回調創建我們創建的接口方法接口onMove(int fromPosition,int toPosition) ,并將拖拽和 Item 的posion和目標posion傳入,posion通過ViewHolder的getAdapterPosition()獲得,然后在滑動回調方法onSwiped中回調onItemDelete(int positon) 。到這里我們自定義的ItemTouchHelper.Callback創建完成。
上面完成后我們只需要在我們自定義的Adapter中實現RecycleItemTouchHelper.ItemTouchHelperCallback接口,然后在回調方法中更新界面,如下Apdater中回調方法實現。
@Override public void onItemDelete(int positon) { list.remove(positon); notifyItemRemoved(positon); } @Override public void onMove(int fromPosition, int toPosition) { Collections.swap(list,fromPosition,toPosition);//交換數據 notifyItemMoved(fromPosition,toPosition); }我們在onItemDelete方法中刪除對應posion的數據,在onMove方法中通過Collections.swap方法交換對應項數據,然后分別調用notifyItemRemoved和notifyItemMoved通過適配器更新UI.
好了到這里功能已經實現了,是不是發現代碼很少,當然 主站蜘蛛池模板: 汉阴县| 乌苏市| 阳江市| 慈利县| 凉城县| 绩溪县| 宿松县| 兖州市| 武冈市| 登封市| 太康县| 五指山市| 永川市| 东阿县| 二连浩特市| 高安市| 抚松县| 三都| 南宁市| 通化县| 东源县| 平安县| 荔浦县| 类乌齐县| 浮梁县| 峨眉山市| 沈阳市| 仁化县| 滦平县| 合川市| 哈巴河县| 增城市| 许昌市| 剑河县| 忻城县| 平邑县| 木兰县| 靖州| 嵩明县| 桐乡市| 琼中|