RecyclerView实现拖动排序和滑动删除功能

来源:互联网 发布:java项目自我评价 编辑:程序博客网 时间:2024/05/21 06:20

RecyclerView 的拖动排序需要借助一下 ItemTouchHelper 这个类,ItemTouchHelper 类是 Google 提供的一个支持 RecyclerView 滑动和拖动的一个使用类,下面使用该类实现 RecyclerView 的滑动删除和拖动排序功能。首先大概介绍一下 ItemTouchHelper 的一个内部抽象类 Callback 类。

ItemTouchHelper.Callback

该类是ItemTouchHelper类中的一个静态抽象类,作用主要是将ItemTouchHelper于自己的应用联系在一起,让开发者通过ViewHolder控制每一个View的具体行为,接收用户的事件回调。该类里面有三个抽象方法:getMovementFlags、onMove、onSwiped。也是开发中经常要是用的。

getMovementFlags

该方法返回一个Flags表示Item的三种状态状态:idle(空闲)、 swiping(滑动)、dragging(拖动),根据RecyclerView不同的布局管理器,设置不同的滑动、拖动方向,一般使用makeMovementFlags(int dragFlags, int swipeFlags)方法返回,dragFlags表示拖动的方向,swipeFlags表示滑动的方向。

public abstract int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder);

onMove

当ItemTouchHelper拖动一个Item时该方法将会被回调,Item将从旧的位置移动到新的位置,如果不拖动这个方法将从来不会调用,返回true表示Item已经被移动到新的位置。

public abstract boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target);

onSwiped

当Item滑动的时候调用,如果不滑动该方法不会被调用,可通过direction做相应的判断执行某些操作。

public abstract void onSwiped(ViewHolder viewHolder, int direction);

此外经常使用的方法有 onSelectedChanged、clearView等方法。

onSelectedChanged

当item由静止状态变为滑动或拖动状态时调用此方法,可通过actionState判断Item在哪种状态下执行某些操作,重写该方法时必须调用其父类的该方法。

public void onSelectedChanged(ViewHolder viewHolder, int actionState) {        if (viewHolder != null) {            sUICallback.onSelected(viewHolder.itemView);        }}

clearView

当与用户交互结束或相关动画完成之后被 调用该方法被调用。

public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {        sUICallback.clearView(viewHolder.itemView);}

RecyclerView实现拖动排序

RecyclerView的拖动排序需要借助一个 android.support.v7.widget.helper.ItemTouchHelper 这个类来实现,拖动排序重点是在接口里面的 onMove(int fromPosition, int toPosition) 方法,其在GridAdapter中的具体实现参考如下:

@Overridepublic 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实现侧滑删除

RecyclerView的拖动排序需要借助一个 android.support.v7.widget.helper.ItemTouchHelper 这个类来实现,侧滑删除重点是在接口中的 onSwiped(int position),其在GridAdapter中的具体实现参考如下:

    @Override    public void onSwiped(int position) {        Log.i("drag","onSwiped");        list.remove(position);        notifyItemRemoved(position);    }

参考代码

ItemTouchHelper.Callback 的实现类

/** * 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);    }}

Adapter的实现

/** * 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;    }}

MainActivity

/** * 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 image image

记录学习历程,分享生活点滴~

<完>

原创粉丝点击