Android实现RecyclerView侧滑删除和长按拖拽-ItemTouchHelper

转:http://blog.csdn.net/kaifa1321/article/details/51817621
http://blog.csdn.net/u010687392/article/details/47950199

list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#F9F9F9"
    android:layout_height="40dp">

    <TextView
        android:id="@+id/iv_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:gravity="center" />

    <ImageView

        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_alignParentBottom="true"
        android:background="#88888888" />

</RelativeLayout>
adapter
package example.com.itemtouchhelper;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.List;

/**
 * Created by Administrator on 2016/12/6.
 */
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
    private Context context;
    private List<String> datas;
    private final LayoutInflater mInflater;

    public ListAdapter(Context context, List<String> datas) {
        this.context = context;
        this.datas = datas;
        mInflater = LayoutInflater.from(context);

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(mInflater.inflate(R.layout.list_item, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        System.out.println("======="+position);
        holder.iv_item.setText(datas.get(position));
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView iv_item;

        public ViewHolder(View itemView) {
            super(itemView);
            iv_item = (TextView) itemView.findViewById(R.id.iv_item);
        }
    }
}

mainActivity
//1.设置适配器
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        final ListAdapter adapter = new ListAdapter(this, datas);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);

        //2.设置ItemTouchHelper
        //0则不执行拖动或者滑动
        ItemTouchHelper.SimpleCallback mCallback = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                int fromPosition = viewHolder.getAdapterPosition();
                int toPosition = target.getAdapterPosition();
                if (fromPosition < toPosition) {
                    //分别把中间所有的item的位置重新交换
                    for (int i = fromPosition; i < toPosition; i++) {
                        Collections.swap(datas, i, i + 1);
                    }
                } else {
                    //分别把中间所有的item的位置重新交换
                    for (int i = fromPosition; i > toPosition; i--) {
                        Collections.swap(datas, i, i - 1);
                    }
                }
                adapter.notifyItemMoved(fromPosition, toPosition);
                //返回true表示执行拖动
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                final int position = viewHolder.getAdapterPosition();
                new AlertDialog.Builder(MainActivity.this)
                        .setCancelable(false)
                        .setMessage("你确定删除该项吗?")
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                adapter.notifyDataSetChanged();
                            }
                        })
                        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                datas.remove(position);
                                adapter.notifyDataSetChanged();
                                Toast.makeText(MainActivity.this, "删除" + position, Toast.LENGTH_SHORT).show();
                            }
                        }).show();

            }

            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                final float alpha = 1 - Math.abs(dX) / (float) viewHolder.itemView.getWidth();
                if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
                    //滑动时改变Item的透明度

                    viewHolder.itemView.setAlpha(alpha);
                    viewHolder.itemView.setTranslationX(dX);
                }
                //防止item复用出现问题,如果大家不理解下面这段代码,可以自行注释效果,
                if (alpha <= 0) {
                    viewHolder.itemView.setAlpha(1);
                    viewHolder.itemView.setTranslationX(dX);

                }
            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                super.onSelectedChanged(viewHolder, actionState);
                //当选中Item时候会调用该方法,重写此方法可以实现选中时候的一些动画逻辑
                Log.v("zxy", "onSelectedChanged");
            }

            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                super.clearView(recyclerView, viewHolder);
                //当动画已经结束的时候调用该方法,重写此方法可以实现恢复Item的初始状态 
                Log.v("zxy", "clearView");
            }
        };
        new ItemTouchHelper(mCallback).attachToRecyclerView(recyclerView);


    }

SimpleCallback构造方法需要我们传入两个参数:

1、dragDirs - 表示拖拽的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
2、swipeDirs - 表示滑动的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
【注】:如果为0,则表示不触发该操作(滑动or拖拽)

然后onMove和onSwiped分别是拖拽和滑动时回调的方法

=====================

temTouchHelper简单使用

要想通过ItemTouchHelper实现交互动画,只需要以下步骤:

  1. 定义一个ItemTouchHelper.Callback回调类,用于实现具体交互效果
  2. 创建一个ItemTouchHelper对象,并传入Callback对象
  3. 调用ItemTouchHelper对象的attachToRecyclerView方法,将ItemTouchHelper对象绑定到指定RecyclerView控件上。

代码如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final List<String> datas = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            datas.add(String.valueOf(i));
        }
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        
        //1.设置适配器
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        RecycleViewAdapter adapter = new RecycleViewAdapter(this, datas);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);
        
        //2.设置ItemTouchHelper
        ItemTouchHelper.Callback callback = new MyItemTouchHelperCallback(adapter);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
        itemTouchHelper.attachToRecyclerView(recyclerView);
	}
}
adpater
package example.com.itemtouchhelper;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

/**
 * Created by Administrator on 2016/12/6.
 */
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.ViewHolder> implements ItemTouchMoveListener {
    private Context context;
    private List<String> datas;
    private final LayoutInflater mInflater;

    public RecycleViewAdapter(Context context, List<String> datas) {
        this.context = context;
        this.datas = datas;
        mInflater = LayoutInflater.from(context);

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(mInflater.inflate(R.layout.list_item, parent, false));
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        System.out.println("=======" + position);
        holder.iv_item.setText(datas.get(position));
    }

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


    public static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView iv_item;

        public ViewHolder(View itemView) {
            super(itemView);
            iv_item = (TextView) itemView.findViewById(R.id.iv_item);
        }
    }

    /**
     * 当Item上下拖动会调用该方法
     *
     * @param fromPosition
     * @param toPosition
     * @return
     */
    @Override
    public boolean onItemMove(int fromPosition, int toPosition) {
        Collections.swap(datas, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
        return true;
    }

    /**
     * 当Item左右滑动时调用该方法
     *
     * @param position
     * @return
     */
    @Override
    public boolean onItemRemove(int position) {
        datas.remove(position);
        notifyItemRemoved(position);
        return true;
    }
}

MyItemTouchHelperCallback
package example.com.itemtouchhelper;

import android.graphics.Canvas;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

/**
 * Created by Administrator on 2016/12/6.
 */
public class MyItemTouchHelperCallback extends ItemTouchHelper.Callback {
    private ItemTouchMoveListener mItemTouchMoveListener;

    public MyItemTouchHelperCallback(ItemTouchMoveListener listener) {
        this.mItemTouchMoveListener = listener;
    }

    /**
     * 设置RecyclerView支持拖动和滑动的方向
     */
    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

        //支持上下拖动
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;

        //支持左右滑动
        int swipeFlag = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;

        int flags = makeMovementFlags(dragFlags, swipeFlag);
        return flags;
    }

    /**
     * 当上下拖动的时候调用该方法
     */
    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        if (viewHolder.getItemViewType() != target.getItemViewType()) {
            // 当item的类型不一样的时候不能交换
            return false;
        }

        boolean result = mItemTouchMoveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
//        boolean result = mItemTouchMoveListener.onItemMove(viewHolder.getLayoutPosition(), target.getLayoutPosition());

        return result;
    }

    /**
     * 当左右滑动的时候调用该方法
     */
    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        mItemTouchMoveListener.onItemRemove(viewHolder.getAdapterPosition());
    }

    /**
     * 选中状态改变时监听
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            //不是空闲状态
            viewHolder.itemView.setBackgroundColor(viewHolder.itemView.getContext().getResources().getColor(R.color.colorPrimary));
        }

        super.onSelectedChanged(viewHolder, actionState);
    }

    /**
     * 恢复item状态
     */
    @Override
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        viewHolder.itemView.setBackgroundColor(Color.parseColor("#F9F9F9"));
        super.clearView(recyclerView, viewHolder);
    }

    /**
     * holde ItemView绘制,属性动画
     */
    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        //在左右滑动时,让item的透明度随着移动而改变,并缩放
        float alpha = 1 - Math.abs(dX) / viewHolder.itemView.getWidth();
        if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
            viewHolder.itemView.setAlpha(alpha);
            viewHolder.itemView.setScaleX(alpha);
            viewHolder.itemView.setScaleY(alpha);

        }
        //防止item复用出现问题,如果大家不理解下面这段代码,可以自行注释效果,
        if (alpha <= 0) {
            viewHolder.itemView.setAlpha(1);
            viewHolder.itemView.setScaleX(1);
            viewHolder.itemView.setScaleY(1);

        }
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }
}

package example.com.itemtouchhelper;

/**
 * Created by Administrator on 2016/12/6.
 */
public interface ItemTouchMoveListener {
    /**
     * 当Item上下拖动时调用
     */
    boolean onItemMove(int fromPosition, int toPosition);

    /**
     * 当item左右滑动时调用
     */
    boolean onItemRemove(int position);
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值