RecyclerView的拖拽 滑动删除效果

从去年RecyclerView的流行起来,到现在还是一直使用ListView(可能已经习惯了吧)  今天有时间来总结一下RecyclerView的使用,主要实现的功能是实现像QQ一样的拖拽效果,还有滑动删除。好了,直接上代码。


public class MainActivity extends Activity implements StarDragLister{

    private RecyclerView rc;
    private List<String> data;
    private ItemTouchHelper itemTouchHelper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rc= (RecyclerView) findViewById(R.id.rc);
        rc.setLayoutManager(new LinearLayoutManager(this));

        data=new ArrayList<String>();
        for(int i=0;i<50;i++){
            data.add(i+"abcde");
        }

        MyAdapter adapter=new MyAdapter(data,this);
        rc.setAdapter(adapter);

        itemTouchHelper=new ItemTouchHelper(new MyItemTouchCallBack(adapter));
        itemTouchHelper.attachToRecyclerView(rc);
    }

    @Override
    public void StarDrag(RecyclerView.ViewHolder holder) {
        itemTouchHelper.startDrag(holder);
    }
}


下面的Adapter:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements ItemTouchHelperAdapterCallBack {

    private List<String> data;

    private StarDragLister lister;

    public MyAdapter(List<String> data, StarDragLister lister) {
        this.data = data;
        this.lister = lister;
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int i) {
        MyViewHolder holder = (MyViewHolder) viewHolder;
        holder.tv.setText(data.get(i));
        holder.tv.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                lister.StarDrag(viewHolder);
                return false;
            }
        });
    }

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

    @Override
    public boolean OnItemMove(int fromPosition, int toPosition) {

        //刷新数据
        Collections.swap(data, fromPosition, toPosition);
        //刷新adapter
        //notifyDataSetChanged();
        //性能优化
        notifyItemMoved(fromPosition, toPosition);
        return false;
    }
    
    @Override
    public void OnItemSwipe(int position) {

        data.remove(position);
        notifyItemRemoved(position);

    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv;
        public MyViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);

        }
    }
}

注意:ItemTouchHelper这个类是最新版本的Sdk里面RecyclerView.jar里面helper包才有的,以前是没有的,
也可以在gradle中这样配置:

还有两个接口:一个是在实现类ItemTouchHelper里面callBack的方法需要把RecyclerView的view拖拽或平移的位置
需要传递给adapter,在使用adapter里面的notifyItemMoved()的方法,来实现效果,为了提高app的性能,尽量不要
使用notifyDataSetChanged(),另一个接口是在监听item里面的一个textView控件,以达到点击textView可以任意更
换位置,此方法是在ItemTouchHelper这个类里面的StarDrag(ViewHolder viewHolder),好了接口的定义基本差不多
啦

下面是两个接口:

public interface ItemTouchHelperAdapterCallBack {

    boolean OnItemMove(int fromPosition ,int toPosition);

    void OnItemSwipe(int position);

}

public interface StarDragLister {
    void StarDrag(RecyclerView.ViewHolder holder);
}

还有就是在点击view时ItemTouchHelper的回调实现类:

public class MyItemTouchCallBack extends ItemTouchHelper.Callback{
   
    ItemTouchHelperAdapterCallBack adapterCallBack;
    public MyItemTouchCallBack( ItemTouchHelperAdapterCallBack adapterCallBack){
        this.adapterCallBack=adapterCallBack;
    }
    @Override
//这是定义view在哪个方向滑动
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

        /**声明是哪个方向的滑动
         * 0001
         * 0010
         * 0100
         * 1000
         */

        int dragFlags=ItemTouchHelper.DOWN|ItemTouchHelper.UP;
        int swipeFlags=ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;

        return makeMovementFlags(dragFlags,swipeFlags);
    }
 
//这是定义view在上下滑动
@Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { adapterCallBack.OnItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition()); return false; }
 
//这是定义view左右滑动
@Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { adapterCallBack.OnItemSwipe(viewHolder.getAdapterPosition()); } @Override public boolean isLongPressDragEnabled() { return true; }

//这是定义滑动是删除的效果,例如动画,渐变等

 // @Override// public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {//// //判断是左右滑动还是上下滑动// //实现滑动删除透明度变化的效果// if(actionState==ItemTouchHelper.ACTION_STATE_SWIPE){//// float alp=1-Math.abs(dX/viewHolder.itemView.getWidth());//// viewHolder.itemView.setAlpha(alp);// viewHolder.itemView.setScaleX(alp);// viewHolder.itemView.setScaleY(alp);//// if(alp<=0){// //因为上面将item的宽和高已经设置成了0 0 所以在view复用的时候会出现空白的bug// viewHolder.itemView.setAlpha(1);// viewHolder.itemView.setScaleX(1);// viewHolder.itemView.setScaleY(1);// }//// //下面是实现滑动删除的效果,在动态添加布局 if(dX<-0.5f*viewHolder.itemView.getWidth()){ viewHolder.itemView.setTranslationX(-0.3f*viewHolder.itemView.getWidth()); }// }else{// super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);// }//// }}

至于布局都是比较简单,大家自己随便定义就好啦!











 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值