RecyclerView 的拖動(dòng)排序需要借助一下 ItemTouchHelper 這個(gè)類,ItemTouchHelper 類是 Google 提供的一個(gè)支持 RecyclerView 滑動(dòng)和拖動(dòng)的一個(gè)使用類,下面使用該類實(shí)現(xiàn) RecyclerView 的滑動(dòng)刪除和拖動(dòng)排序功能。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供方正網(wǎng)站建設(shè)、方正做網(wǎng)站、方正網(wǎng)站設(shè)計(jì)、方正網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、方正企業(yè)網(wǎng)站模板建站服務(wù),10年方正做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
閱讀文本之前可以先閱讀如下文章:
首先大概介紹一下 ItemTouchHelper 的一個(gè)內(nèi)部抽象類 Callback 類。
該類是ItemTouchHelper類中的一個(gè)靜態(tài)抽象類,作用主要是將ItemTouchHelper于自己的應(yīng)用聯(lián)系在一起,讓開發(fā)者通過ViewHolder控制每一個(gè)View的具體行為,接收用戶的事件回調(diào)。該類里面有三個(gè)抽象方法:getMovementFlags、onMove、onSwiped。也是開發(fā)中經(jīng)常要是用的。
該方法返回一個(gè)Flags表示Item的三種狀態(tài)狀態(tài):idle(空閑)、 swiping(滑動(dòng))、dragging(拖動(dòng)),根據(jù)RecyclerView不同的布局管理器,設(shè)置不同的滑動(dòng)、拖動(dòng)方向,一般使用makeMovementFlags(int dragFlags, int swipeFlags)方法返回,dragFlags表示拖動(dòng)的方向,swipeFlags表示滑動(dòng)的方向。
public abstract int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder);
當(dāng)ItemTouchHelper拖動(dòng)一個(gè)Item時(shí)該方法將會(huì)被回調(diào),Item將從舊的位置移動(dòng)到新的位置,如果不拖動(dòng)這個(gè)方法將從來不會(huì)調(diào)用,返回true表示Item已經(jīng)被移動(dòng)到新的位置。
public abstract boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target);
當(dāng)Item滑動(dòng)的時(shí)候調(diào)用,如果不滑動(dòng)該方法不會(huì)被調(diào)用,可通過direction做相應(yīng)的判斷執(zhí)行某些操作。
public abstract void onSwiped(ViewHolder viewHolder, int direction);
此外經(jīng)常使用的方法有 onSelectedChanged、clearView等方法。
當(dāng)item由靜止?fàn)顟B(tài)變?yōu)榛瑒?dòng)或拖動(dòng)狀態(tài)時(shí)調(diào)用此方法,可通過actionState判斷Item在哪種狀態(tài)下執(zhí)行某些操作,重寫該方法時(shí)必須調(diào)用其父類的該方法。
public void onSelectedChanged(ViewHolder viewHolder, int actionState) {
if (viewHolder != null) {
sUICallback.onSelected(viewHolder.itemView);
}
}
當(dāng)與用戶交互結(jié)束或相關(guān)動(dòng)畫完成之后被 調(diào)用該方法被調(diào)用。
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
sUICallback.clearView(viewHolder.itemView);
}
RecyclerView的拖動(dòng)排序需要借助一個(gè) android.support.v7.widget.helper.ItemTouchHelper 這個(gè)類來實(shí)現(xiàn),拖動(dòng)排序重點(diǎn)是在接口里面的 onMove(int fromPosition, int toPosition) 方法,其在GridAdapter中的具體實(shí)現(xiàn)參考如下:
@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的拖動(dòng)排序需要借助一個(gè) android.support.v7.widget.helper.ItemTouchHelper 這個(gè)類來實(shí)現(xiàn),側(cè)滑刪除重點(diǎn)是在接口中的 onSwiped(int position),其在GridAdapter中的具體實(shí)現(xiàn)參考如下:
@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;
}
/**
* 根據(jù) RecyclerView 不同的布局管理器,設(shè)置不同的滑動(dòng)、拖動(dòng)方向
* 該方法使用 makeMovementFlags(int dragFlags, int swipeFlags) 方法返回
* 參數(shù): dragFlags:拖動(dòng)的方向
* swipeFlags:滑動(dòng)的方向
* @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){
//此處不需要進(jìn)行滑動(dòng)操作,可設(shè)置為除4和8之外的整數(shù),這里設(shè)為0
//不支持滑動(dòng)
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN |
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0 );
}else {
//如果是LinearLayoutManager則只能向上向下滑動(dòng),
//此處第二個(gè)參數(shù)設(shè)置支持向右滑動(dòng)
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN , ItemTouchHelper.RIGHT );
}
}
/**
* 當(dāng) ItemTouchHelper 拖動(dòng)一個(gè)Item時(shí)該方法將會(huì)被回調(diào),Item將從舊的位置移動(dòng)到新的位置
* 如果不拖動(dòng)這個(gè)方法將從來不會(huì)調(diào)用,返回true表示已經(jīng)被移動(dòng)到新的位置
* @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;
}
/**
* 當(dāng)Item被滑動(dòng)的時(shí)候被調(diào)用
* 如果你不滑動(dòng)這個(gè)方法將不會(huì)被調(diào)用
* @param viewHolder
* @param direction
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
Log.i(TAG,"onSwiped");
//此處是側(cè)滑刪除的主要代碼
int position = viewHolder.getAdapterPosition();
onItemTouchListener.onSwiped(position);
}
/**
* 當(dāng)Item被滑動(dòng)、拖動(dòng)的時(shí)候被調(diào)用
* @param viewHolder
* @param actionState
*/
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
Log.i(TAG,"onSelectedChanged");
//...
super.onSelectedChanged(viewHolder, actionState);
}
/**
* 當(dāng)與用戶交互結(jié)束或相關(guān)動(dòng)畫完成之后被調(diào)用
* @param recyclerView
* @param viewHolder
*/
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
Log.i(TAG,"clearView");
//...
super.clearView(recyclerView, viewHolder);
}
/**
* 移動(dòng)交換數(shù)據(jù)的更新監(jiān)聽
*/
public interface OnItemTouchListener {
//拖動(dòng)Item時(shí)調(diào)用
void onMove(int fromPosition, int toPosition);
//滑動(dòng)Item時(shí)調(diào)用
void onSwiped(int position);
}
}
/**
* Created by jzman on 2017/05/17 0009.
* RecycleView的Adapter
*/
public class GridAdapter extends RecyclerView.Adapter implements View.OnClickListener,ItemTouchCallBack.OnItemTouchListener {
private Context context;
private List list;
public GridAdapter(Context context, List list) {
this.context = context;
this.list = list;
}
/**
* 創(chuàng)建ViewHolder
* @param parent
* @param viewType
* @return
*/
@Override
public DataViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//加載item布局文件(每一個(gè))
View view = LayoutInflater.from(context).inflate(R.layout.item,null);
//為View設(shè)置單擊事件
view.setOnClickListener(this);
DataViewHolder viewHolder = new DataViewHolder(view);
//使用代碼設(shè)置寬高(xml布局設(shè)置無效時(shí))
view.setLayoutParams(new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
return viewHolder;
}
/**
* 綁定數(shù)據(jù)
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(DataViewHolder holder, int position) {
//設(shè)置每一個(gè)Item的高度
holder.textView.setText(list.get(position).getTitle());
}
/**
* 選項(xiàng)總數(shù)
* @return
*/
@Override
public int getItemCount() {
return list.size();
}
/**
* 單擊事件
* @param v
*/
@Override
public void onClick(View v) {
if(onItemClickListener!=null){
int position = recyclerView.getChildAdapterPosition(v);
//程序執(zhí)行到此,會(huì)執(zhí)行該方法的具體實(shí)現(xiàn)
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中針對(duì)ViewHolder來實(shí)現(xiàn)
*/
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;
}
/**
* 設(shè)計(jì)recycleView選項(xiàng)單擊事件的回調(diào)接口(給外面使用)
* 參考ListView選項(xiàng)單擊事件方法
*/
public interface OnItemClickListener{
//參數(shù)(父組件,點(diǎn)擊的View,位置,這里可能是某個(gè)對(duì)象的id或?qū)ο?這里不需要)
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 |
---|---|
可關(guān)注微信公眾號(hào):jzman-blog獲取最新文章更新,一起交流學(xué)習(xí)!
cdn.xitu.io/2019/4/25/16a549fb5d367d94?w=600&h=472&f=jpeg&s=21120">