使用ItemTouchHelper类轻松实现RecyclerView的拖拽和侧滑

在android的support-v7包中,关注度最高的控件莫过于RecyclerView这个控件了,使用RecyclerView的好处多多,这里也不再赘述。今天要说的主角是ItemTouchHelper这个类,这个类同样是在support-v7的包中,从这个类的描述上来看是这样的。

This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.

从描述上可以看到这个类是RecyclerView的一个帮助类,用来实现滑动删除和拖拽功能的。

直接上代码:

package com.app.motiongear.swipeanddragmotion;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.zhy.sample.demo_recyclerview.DividerItemDecoration;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private List<String> mDatas = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initDatas();
        initViews();
        makeAdapter();
    }

    /**
     * 初始化view
     */
    private void initViews() {
        mRecyclerView = (RecyclerView) this.findViewById(R.id.recyclerview);
    }

    /**
     * 初始化数据
     */
    private void initDatas() {
        String[] numberic = this.getResources().getStringArray(R.array.numberic);
        for (String value : numberic) {
            mDatas.add(value);
        }
    }

    /**
     * 设置RecyclerView的adapter
     */
    private void makeAdapter() {
        CustomRecyclerViewAdapter adapter = new CustomRecyclerViewAdapter(this, mDatas);
        mRecyclerView.setAdapter(adapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
        //设置ItemTouchHelper类
        SimpleTouchHelperCallback callback = new SimpleTouchHelperCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(mRecyclerView);
    }

    /**
     * 定义拖拽和侧滑接口
     */
    public interface OnDragAndSwipeListener {
        public boolean onItemMove(int fromPosition, int toPosition);

        public void onItemDismiss(int position);
    }

    /**
     * 自定义RecyclerVIewAdapter,实现OnDragAndSwipeListener接口
     */
    public static class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CustomViewHolder>
            implements OnDragAndSwipeListener {
        private List<String> datas;
        private Context context;
        private LayoutInflater inflater;

        public CustomRecyclerViewAdapter(Context context, List<String> data) {
            this.context = context;
            datas = data;
            inflater = LayoutInflater.from(context);
        }

        @Override
        public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = inflater.inflate(R.layout.layout_item, null);
            v.setBackgroundColor(Color.parseColor("#FFF0F5"));
            CustomViewHolder viewHolder = new CustomViewHolder(v);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(CustomViewHolder holder, int position) {
            holder.tv.setText(datas.get(position));
        }

        @Override
        public int getItemCount() {
            return datas.size();
        }

        @Override
        public boolean onItemMove(int fromPosition, int toPosition) {
            //交换拖拽过程中的数据
            Collections.swap(datas, fromPosition, toPosition);
            notifyItemMoved(fromPosition, toPosition);
            return true;
        }

        @Override
        public void onItemDismiss(int position) {
            //删除移除的数据
            datas.remove(position);
            notifyItemRemoved(position);
        }
    }

    public static class CustomViewHolder extends RecyclerView.ViewHolder {

        public TextView tv;

        public CustomViewHolder(View view) {
            super(view);
            tv = (TextView) view.findViewById(R.id.tv_title);
        }
    }

    /**
     * 自定义一个ItemTouchHelper.Callback的类,用来构建ItemTouchHelper
     */
    public static class SimpleTouchHelperCallback extends ItemTouchHelper.Callback {
        CustomRecyclerViewAdapter adapter;

        public SimpleTouchHelperCallback(CustomRecyclerViewAdapter adapter) {
            this.adapter = adapter;
        }

        @Override
        public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
            final int dragMode = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            final int moveMode = ItemTouchHelper.START | ItemTouchHelper.END;
            return makeMovementFlags(dragMode, moveMode);
        }

        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            //调用adapter中的onMove()方法
            return adapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            //调用adapter中的onSwiped()方法
            adapter.onItemDismiss(viewHolder.getAdapterPosition());
        }
    }
}

代码还是比较简单的,我们定义一个SimpleTouchHelperCallback类,在这个类中重写了getMovementFlags()、onMove()和onSwiped()三个方法。在getMovementFlags中定义了 我们拖拽和滑动的方法。在onMove()和onSwiped()方法中定义了滑动和删除的逻辑处理,从结果上来看拖动是交换了数据,侧滑是删除了指定位置的信息,这两个方法都可以直接操作数据集合datas中的数据,最后显示在列表上。所以处理流程也可以总结为下面几部:

  • 自定义接口,添加拖拽和侧滑的接口
  • 在自定义的RecyclerView.Adapter中实现这个接口
  • 自定义ItemTouchHelprCallback类,并且传入Adapter
  • 将ItemTouchHelper绑定到RecylcerView上
posted @ 2016-05-17 01:02  豌豆豆  阅读(142)  评论(0)    收藏  举报