继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

哈士奇WWW
关注TA
已关注
手记 503
粉丝 71
获赞 400

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();
    }
}

显示效果

GridLayoutManagerLinearLayoutManager
图片描述图片描述

原文链接:http://www.apkbus.com/blog-907060-77738.html

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP