RecyclerView 的拖動排序須要藉助一下 ItemTouchHelper 這個類,ItemTouchHelper 類是 Google 提供的一個支持 RecyclerView 滑動和拖動的一個使用類,下面使用該類實現 RecyclerView 的滑動刪除和拖動排序功能。首先大概介紹一下 ItemTouchHelper 的一個內部抽象類 Callback 類。java
該類是ItemTouchHelper類中的一個靜態抽象類,做用主要是將ItemTouchHelper於本身的應用聯繫在一塊兒,讓開發者經過ViewHolder控制每個View的具體行爲,接收用戶的事件回調。該類裏面有三個抽象方法:getMovementFlags、onMove、onSwiped。也是開發中常常要是用的。android
該方法返回一個Flags表示Item的三種狀態狀態:idle(空閒)、 swiping(滑動)、dragging(拖動),根據RecyclerView不一樣的佈局管理器,設置不一樣的滑動、拖動方向,通常使用makeMovementFlags(int dragFlags, int swipeFlags)方法返回,dragFlags表示拖動的方向,swipeFlags表示滑動的方向。微信
public abstract int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder);
當ItemTouchHelper拖動一個Item時該方法將會被回調,Item將從舊的位置移動到新的位置,若是不拖動這個方法將歷來不會調用,返回true表示Item已經被移動到新的位置。ide
public abstract boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target);
當Item滑動的時候調用,若是不滑動該方法不會被調用,可經過direction作相應的判斷執行某些操做。佈局
public abstract void onSwiped(ViewHolder viewHolder, int direction);
此外常常使用的方法有 onSelectedChanged、clearView等方法。學習
當item由靜止狀態變爲滑動或拖動狀態時調用此方法,可經過actionState判斷Item在哪一種狀態下執行某些操做,重寫該方法時必須調用其父類的該方法。動畫
public void onSelectedChanged(ViewHolder viewHolder, int actionState) { if (viewHolder != null) { sUICallback.onSelected(viewHolder.itemView); } }
當與用戶交互結束或相關動畫完成以後被 調用該方法被調用。this
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) { sUICallback.clearView(viewHolder.itemView); }
RecyclerView的拖動排序須要藉助一個 android.support.v7.widget.helper.ItemTouchHelper 這個類來實現,拖動排序重點是在接口裏面的 onMove(int fromPosition, int toPosition) 方法,其在GridAdapter中的具體實現參考以下:設計
@Override public void onMove(int fromPosition, int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(list, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(list, i, i - 1); } } notifyItemMoved(fromPosition, toPosition); }
RecyclerView的拖動排序須要藉助一個 android.support.v7.widget.helper.ItemTouchHelper 這個類來實現,側滑刪除重點是在接口中的 onSwiped(int position),其在GridAdapter中的具體實現參考以下:code
@Override public void onSwiped(int position) { Log.i("drag","onSwiped"); list.remove(position); notifyItemRemoved(position); }
/** * Created by jzman on 2017/5/17 0015. */ public class ItemTouchCallBack extends ItemTouchHelper.Callback { private static final String TAG = "drag"; private OnItemTouchListener onItemTouchListener; public void setOnItemTouchListener(OnItemTouchListener onItemTouchListener) { this.onItemTouchListener = onItemTouchListener; } /** * 根據 RecyclerView 不一樣的佈局管理器,設置不一樣的滑動、拖動方向 * 該方法使用 makeMovementFlags(int dragFlags, int swipeFlags) 方法返回 * 參數: dragFlags:拖動的方向 * swipeFlags:滑動的方向 * @param recyclerView * @param viewHolder * @return */ @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { Log.i(TAG,"getMovementFlags"); if (recyclerView.getLayoutManager() instanceof GridLayoutManager || recyclerView.getLayoutManager() instanceof StaggeredGridLayoutManager){ //此處不須要進行滑動操做,可設置爲除4和8以外的整數,這裏設爲0 //不支持滑動 return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0 ); }else { //若是是LinearLayoutManager則只能向上向下滑動, //此處第二個參數設置支持向右滑動 return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN , ItemTouchHelper.RIGHT ); } } /** * 當 ItemTouchHelper 拖動一個Item時該方法將會被回調,Item將從舊的位置移動到新的位置 * 若是不拖動這個方法將歷來不會調用,返回true表示已經被移動到新的位置 * @param recyclerView * @param viewHolder * @param target * @return */ @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { Log.i(TAG,"onMove"); int fromPosition = viewHolder.getAdapterPosition(); int toPosition = target.getAdapterPosition(); onItemTouchListener.onMove(fromPosition,toPosition); return true; } /** * 當Item被滑動的時候被調用 * 若是你不滑動這個方法將不會被調用 * @param viewHolder * @param direction */ @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { Log.i(TAG,"onSwiped"); //此處是側滑刪除的主要代碼 int position = viewHolder.getAdapterPosition(); onItemTouchListener.onSwiped(position); } /** * 當Item被滑動、拖動的時候被調用 * @param viewHolder * @param actionState */ @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { Log.i(TAG,"onSelectedChanged"); //... super.onSelectedChanged(viewHolder, actionState); } /** * 當與用戶交互結束或相關動畫完成以後被調用 * @param recyclerView * @param viewHolder */ @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { Log.i(TAG,"clearView"); //... super.clearView(recyclerView, viewHolder); } /** * 移動交換數據的更新監聽 */ public interface OnItemTouchListener { //拖動Item時調用 void onMove(int fromPosition, int toPosition); //滑動Item時調用 void onSwiped(int position); } }
/** * Created by jzman on 2017/05/17 0009. * RecycleView的Adapter */ public class GridAdapter extends RecyclerView.Adapter<GridAdapter.DataViewHolder> implements View.OnClickListener,ItemTouchCallBack.OnItemTouchListener { private Context context; private List<SimpleTitleGrid> list; public GridAdapter(Context context, List<SimpleTitleGrid> list) { this.context = context; this.list = list; } /** * 建立ViewHolder * @param parent * @param viewType * @return */ @Override public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //加載item佈局文件(每個) View view = LayoutInflater.from(context).inflate(R.layout.item,null); //爲View設置單擊事件 view.setOnClickListener(this); DataViewHolder viewHolder = new DataViewHolder(view); //使用代碼設置寬高(xml佈局設置無效時) view.setLayoutParams(new RecyclerView.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); return viewHolder; } /** * 綁定數據 * @param holder * @param position */ @Override public void onBindViewHolder(DataViewHolder holder, int position) { //設置每個Item的高度 holder.textView.setText(list.get(position).getTitle()); } /** * 選項總數 * @return */ @Override public int getItemCount() { return list.size(); } /** * 單擊事件 * @param v */ @Override public void onClick(View v) { if(onItemClickListener!=null){ int position = recyclerView.getChildAdapterPosition(v); //程序執行到此,會執行該方法的具體實現 onItemClickListener.onItemClick(recyclerView,v,position,list.get(position)); } } @Override public void onMove(int fromPosition, int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(list, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(list, i, i - 1); } } notifyItemMoved(fromPosition, toPosition); } @Override public void onSwiped(int position) { Log.i("drag","onSwiped"); list.remove(position); notifyItemRemoved(position); } /** * RecycleView中針對ViewHolder來實現 */ public static class DataViewHolder extends RecyclerView.ViewHolder { TextView textView; public DataViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.tv_grid); } } private RecyclerView recyclerView; private OnItemClickListener onItemClickListener; public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } /** * 設計recycleView選項單擊事件的回調接口(給外面使用) * 參考ListView選項單擊事件方法 */ public interface OnItemClickListener{ //參數(父組件,點擊的View,位置,這裏多是某個對象的id或對象/這裏不須要) void onItemClick(RecyclerView recyclerView, View view, int position, SimpleTitleGrid obj); } /** * 將RecycleView附加到Adapter上 */ @Override public void onAttachedToRecyclerView(RecyclerView recyclerView) { super.onAttachedToRecyclerView(recyclerView); this.recyclerView= recyclerView; } /** * 將RecycleView從Adapter解除 */ @Override public void onDetachedFromRecyclerView(RecyclerView recyclerView) { super.onDetachedFromRecyclerView(recyclerView); this.recyclerView = null; } }
/** * Created by jzman on 2017/05/17 0029. * RecycleView的Adapter */ public class MainActivity extends AppCompatActivity implements GridAdapter.OnItemClickListener{ private RecyclerView rv_user; private GridAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { rv_user = (RecyclerView) findViewById(R.id.rv_user); adapter = new GridAdapter(this, DataUtils.getUserGrids()); ItemTouchCallBack touchCallBack = new ItemTouchCallBack(); touchCallBack.setOnItemTouchListener(adapter); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(touchCallBack); rv_user.setLayoutManager(new GridLayoutManager(this,3)); // rv_user.setLayoutManager(new LinearLayoutManager(this)); rv_user.setAdapter(adapter); itemTouchHelper.attachToRecyclerView(rv_user); adapter.setOnItemClickListener(this); } @Override public void onItemClick(RecyclerView recyclerView, View view, int position, SimpleTitleGrid obj) { Toast.makeText(MainActivity.this, obj.getTitle(), Toast.LENGTH_SHORT).show(); } }
GridLayoutManager
LinearLayoutManager
|
能夠選擇關注微信公衆號:jzman-blog 獲取最新更新,一塊兒交流學習!