ItemTouchHelper,让你轻松打造RecyclerView中Item的滑动删除,拖

ItemTouchHelper,让你轻松打造RecyclerView中Item的滑动删除,拖拽交换

Androidswipe

ItemTouchHelper是什么?

ItemTouchHelper是v7包中的用于为RecyclerView中Item操作提供帮助的工具类。

/** * This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView. * <p> * XXXXXXXXXXXXXXXXXXXXXXXXXXXXX */public class ItemTouchHelper extends RecyclerView.ItemDecorationimplements RecyclerView.OnChildAttachStateChangeListener {

它内部封装了 Item的左右滑动,上下平移的操作,并向外提供了一个Callback抽象类让我们使用

/*** This class is the contract between ItemTouchHelper and your application. It lets you control* which touch behaviors are enabled per each ViewHolder and also receive callbacks when user* performs these actions.<span style="white-space:pre"></span>XXXXXXXX*/@SuppressWarnings("UnusedParameters")public abstract static class Callback {我们使用的 时候只需继承该类并实现其中的几个抽象方法就可以轻松实现诸如Item的滑动删除,拖拽交换。不用我们再自己去实现复杂的交互逻辑。默认一共有三个抽象方法需要实现 /*** Should return a composite flag which defines the enabled move directions in each state* (idle, swiping, dragging).* <p>* Instead of composing this flag manually, you can use {@link #makeMovementFlags(int,* int)}* or {@link #makeFlag(int, int)}.* <p>* This flag is composed of 3 sets of 8 bits, where first 8 bits are for IDLE state, next* 8 bits are for SWIPE state and third 8 bits are for DRAG state.* Each 8 bit sections can be constructed by simply OR'ing direction flags defined in* {@link ItemTouchHelper}.* <p>* For example, if you want it to allow swiping LEFT and RIGHT but only allow starting to* swipe by swiping RIGHT, you can return:* <pre>*makeFlag(ACTION_STATE_IDLE, RIGHT) | makeFlag(ACTION_STATE_SWIPE, LEFT | RIGHT);* </pre>* This means, allow right movement while IDLE and allow right and left movement while* swiping.** @param recyclerView The RecyclerView to which ItemTouchHelper is attached.* @param viewHolder The ViewHolder for which the movement information is necessary.* @return flags specifying which movements are allowed on this ViewHolder.* @see #makeMovementFlags(int, int)* @see #makeFlag(int, int)*/public abstract int getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder); /*** Called when ItemTouchHelper wants to move the dragged item from its old position to* the new position.* <p>* If this method returns true, ItemTouchHelper assumes {@code viewHolder} has been moved* to the adapter position of {@code target} ViewHolder* ({@link ViewHolder#getAdapterPosition()* ViewHolder#getAdapterPosition()}).* <p>* If you don't support drag & drop, this method will never be called.** @param recyclerView The RecyclerView to which ItemTouchHelper is attached to.* @param viewHolder The ViewHolder which is being dragged by the user.* @param targetThe ViewHolder over which the currently active item is being*dragged.* @return True if the {@code viewHolder} has been moved to the adapter position of* {@code target}.* @see #onMoved(RecyclerView, ViewHolder, int, ViewHolder, int, int, int)*/public abstract boolean onMove(RecyclerView recyclerView,ViewHolder viewHolder, ViewHolder target);/*** Called when a ViewHolder is swiped by the user.* <p>* If you are returning relative directions ({@link #START} , {@link #END}) from the* {@link #getMovementFlags(RecyclerView, ViewHolder)} method, this method* will also use relative directions. Otherwise, it will use absolute directions.* <p>* If you don't support swiping, this method will never be called.* <p>* ItemTouchHelper will keep a reference to the View until it is detached from* RecyclerView.* As soon as it is detached, ItemTouchHelper will call* {@link #clearView(RecyclerView, ViewHolder)}.** @param viewHolder The ViewHolder which has been swiped by the user.* @param direction The direction to which the ViewHolder is swiped. It is one of*{@link #UP}, {@link #DOWN},*{@link #LEFT} or {@link #RIGHT}. If your*{@link #getMovementFlags(RecyclerView, ViewHolder)}*method*returned relative flags instead of {@link #LEFT} / {@link #RIGHT};*`direction` will be relative as well. ({@link #START} or {@link*#END}).*/public abstract void onSwiped(ViewHolder viewHolder, int direction);<strong>getMovementFlags(RecyclerView recyclerView,ViewHolder viewHolder):</strong>该方法的返回值决定的所支持的滑动,拖拽的方向,有ItemTouchHelper.UP, ItemTouchHelper.DOWN ,ItemTouchHelper.LEFT,ItemTouchHelper.RIGHT,ItemTouchHelper.START, ItemTouchHelper.END等几种,比如划动删除的时候,只需要返ItemTouchHelper.LEFT,ItemTouchHelper.RIGHT,即可以支持左右的滑动删除。<strong><onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target):</strong>在拖拽Item的时候调用该方法,第一个ViewHolder代表正在拖拽的Item,第二个ViewHolder代表目标Item</pre><pre name="code" class="java"><strong>onSwiped(ViewHolder viewHolder, int direction):</strong>在滑动Item的时候调用该方法,第二个参数代表拖拽方向的相对位置。</pre><pre name="code" class="java">实际运用中还有几个方法需要重写:</pre><pre name="code" class="java"><strong>isLongPressDragEnabled():</strong>返回true代表支持当长按的时候开始拖拽操作</pre><pre name="code" class="java"><strong>isItemViewSwipeEnabled():</strong>返回true代表支持ItemView的左右滑动</pre><pre name="code" class="java"><strong>onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) :</strong>当系统绘制RecyclerView的时候会调用该方法,你可以重写改方法在里面写动画逻辑。其中cationState一共有三种,IDLE, SWIPE, DRAG分别代表了 静止,滑动,拖拽三种状态,</pre><pre name="code" class="java"><strong>onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) :</strong>在Item选中状态该表的时候会调用该方法,可以重写改方法,当选中时,写一些动画逻辑。</pre><pre name="code" class="java"><strong>clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) : </strong>当用户的操作和动画已经结束的时候调用该方法,可以重写该方法,恢复Item的初始状态说了这么多,不如用代码来解释。<span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="java"><pre name="code" class="java">import android.graphics.Canvas;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.helper.ItemTouchHelper;import android.util.Log;/** * Created by haggling on 2015/8/6. */public class MyTouchHelperCallback extends ItemTouchHelper.Callback {public static final float ALPHA_FULL = 1.0f;private final ItemTouchHelperAdapter adapter;public MyTouchHelperCallback(ItemTouchHelperAdapter adapter) {this.adapter = adapter;}/*** 支持长按开始拖拽* @return*/@Overridepublic boolean isLongPressDragEnabled() {return true;}/*** 支持左右滑动* @return*/@Overridepublic boolean isItemViewSwipeEnabled() {return true;}@Overridepublic int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {//滑动的时候支持的方向int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;//拖拽的时候支持的方向int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;//必须调用该方法告诉ItemTouchHelper支持的flagsreturn makeMovementFlags(dragFlags, swipeFlags);}/*** Item移动的时候调用该方法* @param recyclerView* @param viewHolder* @param target* @return*/@Overridepublic boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {if(viewHolder.getItemViewType() != target.getItemViewType()) {return false;}adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());return true;}/*** Item滑动的时候调用该方法* @param viewHolder* @param direction*/@Overridepublic void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {adapter.onItemDismiss(viewHolder.getAdapterPosition());}@Overridepublic void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {if(actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {//左右滑动时改变Item的透明度final float alpha = ALPHA_FULL – Math.abs(dX) / (float)viewHolder.itemView.getWidth();viewHolder.itemView.setAlpha(alpha);viewHolder.itemView.setTranslationX(dX);} else {super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);}}@Overridepublic void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {if(actionState != ItemTouchHelper.ACTION_STATE_IDLE) {Log.d("ACTION_STATE_IDLE", "ACTION_STATE_IDLE");if(viewHolder instanceof ItemTouchHelperViewHolder) {Log.d("instanceof", "instanceof");ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder)viewHolder;itemViewHolder.onItemSelected();}}super.onSelectedChanged(viewHolder, actionState);}@Overridepublic void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {super.clearView(recyclerView, viewHolder);Log.d("clearView", "clearView");viewHolder.itemView.setAlpha(ALPHA_FULL);if(viewHolder instanceof ItemTouchHelperViewHolder) {ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder)viewHolder;itemViewHolder.onItemClear();}}}<strong>其中有三个接口</strong><span style="font-family: Arial, Helvetica, sans-serif;"></span><pre name="code" class="java">public interface ItemTouchHelperAdapter {boolean onItemMove(int fromPosition, int toPosition);void onItemDismiss(int position);}public interface ItemTouchHelperViewHolder {void onItemSelected();void onItemClear();}/** * Created by haoqinling on 2015/8/6. */import android.support.v7.widget.RecyclerView;public interface OnStartDragListener {void onStartDrag(RecyclerView.ViewHolder viewHolder);}

RecyclerView的Adapter的这一半更多地赢取上帝掌握的那一半。

ItemTouchHelper,让你轻松打造RecyclerView中Item的滑动删除,拖

相关文章:

你感兴趣的文章:

标签云: