Android基础——RecyclerView拖拽排序侧滑删除

Android基础——RecyclerView拖拽排序侧滑删除


额,关于RecyclerView就不过多的解释了,大家应该都比较了解它了,鸿洋博客有比较详细的解释:Android RecyclerView 使用完全解析 体验艺术般的控件。写本篇博客的目的就是,自己在学习的过程中想要实现该功能,想做个笔记哈,所以就有了本篇博客喽~


item布局

我们知道无论是RecyclerView还是ListView都需要item的,额……这个布局实在没什么可说的,毕竟每个人的item都不相同嘛,如下的布局代码是模仿微信的,代码如下:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="#ffffff"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="8dp">

        <ImageView
            android:id="@+id/iv_icon"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@mipmap/ic_launcher" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:padding="4dp">

                <TextView
                    android:id="@+id/tv_username"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="4dp"
                    android:layout_weight="1"
                    android:text="李林雄"
                    android:textColor="#000000"
                    android:textSize="16dp" />

                <TextView
                    android:id="@+id/tv_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="22:10"
                    android:textColor="#888888"
                    android:textSize="14dp" />

            LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:paddingLeft="4dp">

                <TextView
                    android:id="@+id/tv_message"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="4dp"
                    android:text="干嘛呢"
                    android:textColor="#888888"
                    android:textSize="14dp" />
            LinearLayout>
        LinearLayout>
    LinearLayout>
LinearLayout>

Bean

有了item布局,我们就该有相对应的Bean啦,这个是必须的,Bean代码如下:

package com.example.lilinxiong.recycleviewdragdrop;

/**
 * 项目名:  RecycleViewDragDrop
 * 包名:    com.example.lilinxiong.recycleviewdragdrop
 * 文件名:   Bean
 * 创建者:   LLX
 * 创建时间:  2017/3/28 17:22
 * 描述:    Bean
 */
public class Bean {
    //名字
    private String username;
    //时间
    private String time;
    //消息内容
    private String message;
    //头像id
    private int img_id;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getImg_id() {
        return img_id;
    }

    public void setImg_id(int img_id) {
        this.img_id = img_id;
    }
}

适配器是必须的

package com.example.lilinxiong.recycleviewdragdrop;

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

import java.util.List;

/**
 * 项目名:  RecycleViewDragDrop
 * 包名:    com.example.lilinxiong.recycleviewdragdrop
 * 文件名:   RecycleViewAdapter
 * 创建者:   LLX
 * 创建时间:  2017/3/28 17:29
 * 描述:    RecyclerView适配器
 */
public class RecycleViewAdapter extends RecyclerView.Adapter.ViewHolder> {
    //List数据
    private List beanList;

    public RecycleViewAdapter(List beanList) {
        this.beanList = beanList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycleview_item, parent, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Bean bean = beanList.get(position);
        holder.iv_icon.setImageResource(bean.getImg_id());
        holder.tv_username.setText(bean.getUsername());
        holder.tv_time.setText(bean.getTime());
        holder.tv_message.setText(bean.getMessage());
    }

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

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView iv_icon;
        TextView tv_username;
        TextView tv_time;
        TextView tv_message;

        public ViewHolder(View view) {
            super(view);
            iv_icon = (ImageView) view.findViewById(R.id.iv_icon);
            tv_username = (TextView) view.findViewById(R.id.tv_username);
            tv_time = (TextView) view.findViewById(R.id.tv_time);
            tv_message = (TextView) view.findViewById(R.id.tv_message);
        }
    }
}

实现拖拽排序、侧滑删除效果

万事具备,现在就来实现我们的拖拽排序,侧滑删除效果吧。我们先来捋一下逻辑哈!


  • 绑定RecyclerView控件

  • 数据、adapter初始化

  • layoutManager初始化(若是想实现线性的拖拽排序则初始化LinearLayoutManager)

  • RecyclerView设置layoutManager

  • RecyclerView设置适配器

  • ItemTouchHelper(这个才是重点)

使用一个RecyclerView这些条件是必不可少的,绑定id,数据和adapter初始化这些是必须的,layoutManager则是控制数据在RecyclerView如何显示的,然后接下来就是为RecyclerView设置layoutManager和设置adapter了。
最后一个就是实现拖拽排序、侧滑删除的关键了。嘿嘿,还是在代码中讲解吧,这样讲的话太空洞了,OK,代码如下:

package com.example.lilinxiong.recycleviewdragdrop;

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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecycleViewAdapter adapter;
    private List beanList;
    private LinearLayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化控件
        initView();
        //初始化数据
        initData();

    //初始化数据
    private void initData() {
        for (int i = 0; i < 20; i++) {
            Bean bean = new Bean();
            bean.setImg_id(R.mipmap.ic_launcher);
            bean.setTime("2017-03-28");
            bean.setMessage("今天我学习到了RecyclerView拖拽排序、RecyclerView侧滑删除");
            bean.setUsername("李林雄");
            beanList.add(bean);
        }
        adapter.notifyDataSetChanged();
    }

    //初始化控件
    private void initView() {
        //绑定id
        mRecyclerView = (RecyclerView) findViewById(R.id.mRecyclerView);
        //beanList初始化
        beanList = new ArrayList<>();
        //adapter初始化
        adapter = new RecycleViewAdapter(beanList);
        //layoutManager初始化
        layoutManager = new LinearLayoutManager(this);
        //RecyclerView设置layoutManager
        mRecyclerView.setLayoutManager(layoutManager);
        //RecyclerView绑定适配器
        mRecyclerView.setAdapter(adapter);
    }
}

如上代码就是使用RecyclerView所做的事儿了,若是想实现RecyclerView的拖拽排序、侧滑删除,则需要如下代码了,如下:

        ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                //首先回调的方法 返回int表示是否监听该方向
                int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;//线性排列时监听到的为上下动作则为:拖拽排序
                int swipeFlags = ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;//线性排列时监听到的为左右动作时则为:侧滑删除
                return makeMovementFlags(dragFlags, swipeFlags);
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                //滑动事件
                //交换位置
                Collections.swap(beanList, viewHolder.getAdapterPosition(), target.getAdapterPosition());
                //刷新adapter
                adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                //侧滑事件
                beanList.remove(viewHolder.getAdapterPosition());
                //刷新adapter
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
            }

            @Override
            public boolean isLongPressDragEnabled() {
                //是否可拖拽
                return true;
            }
        });
        helper.attachToRecyclerView(mRecyclerView);

这段代码的逻辑就是,首先我监听现在的动作是什么,即!手指为上下移动还是左右移动,上下则去交换item的位置,左右移动则将该item的数据从list中remove,然后再刷新adapter就好了,上下为拖拽,那么我们就应该在isLongPressDragEnabled中返回true,即,允许拖拽!最后,设置下生效的RecyclerView就好了,即!helper.attachToRecyclerView()这句代码!大致逻辑就这样子了,其他的看下代码中的注释吧,我感觉挺清楚的了,嘿嘿!看下效果吧:

若是我们想要实现如下的效果呢:

嘿嘿,也就是表格的哈,有点儿丑,不要介意哈,毕竟实现效果就好了嘛,若想实现以上效果,改动的地方并不大,首先我们要将mRecyclerView.setLayoutManager();中的格式改为GridLayoutManager的,然后由于现在我们用不到右滑或者左滑删除了,那么我们ItemTouchHelper中的监听方向的方法也改一改啦,其他的不用更改,代码如下:

...
        GridLayoutManager gridLayoutManager = new GridLayoutManager(MainActivity.this, 2);
        //RecyclerView设置layoutManager
        mRecyclerView.setLayoutManager(gridLayoutManager);
...

new GridLayoutManager(MainActivity.this, 2),该方法中需要传两个参数,第一个是,Context,第二个就是,每行显示几个item。

            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                //首先回调的方法 返回int表示是否监听该方向
                int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
                int swipeFlags = 0;
                return makeMovementFlags(dragFlags, swipeFlags);
            }

由于我们用不到swipeFlags则给它值为0就好了,OK,这样修改完后,上图的效果就实现啦!是不是很简单呢?


关于RecyclerView有很多博客的,比如鸿洋大神的为RecyclerView打造通用Adapter 让RecyclerView更加好用,当然还有开篇提到的那篇哈,关于RecyclerView几乎都包括了呢。

额,有一点,那个主布局的代码没有写,当然还有闭包哈,闭包就一句话“compile ‘com.android.support:recyclerview-v7:25.2.0’”,主布局就一个RecyclerView,没啥的,所以就不贴代码了哈,嘻嘻~

大家若是有什么不懂的,可以在下面评论区中留言哈,我看到后会回的,另外对android有兴趣的同学可以加我们程序员刘某人的群:555974449,群里面有很多大神的,而且很热情,很热心的,大家不懂的可以问的。

Demo下载

你可能感兴趣的:(android,布局,android基础)