Android基础控件——RecyclerView实现拖拽排序侧滑删除效果

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


事先说明:

RecyclerView是ListView的升级版,使用起来比ListView更规范,而且功能和动画可以自己添加,极容易扩展,同样也继承了ListView复用convertView和ViewHolder的优点。


思路分析:

1、导包、在布局中使用RecyclerView

2、需要一个JavaBean用来存储展示信息

3、需要一个填充RecyclerView的布局文件

4、在代码中找到RecyclerView,并为其绑定Adapter和触摸事件

5、适配器的编写、触摸事件的处理

总体上跟ListView是一样的,就是换了一种代码风格


思路图解:



效果一(线性布局):                                                                         效果二(网格布局):

   


步骤一:RecyclerView是在support.v7包,Android Studio则是recyclerview这个包



步骤二:创建布局文件,使用recyclerview

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F4F4F3"
    android:orientation="vertical"
    tools:context="com.handsome.app3.MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/top" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bottom" />
</LinearLayout>

步骤三:创建一个javaBean,存储item的信息

public class Message {

    private String username;
    private String time;
    private String message;
    private int img_id;

    public Message(String username, String time, String message, int img_id) {
        this.username = username;
        this.time = time;
        this.message = message;
        this.img_id = 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;
    }
}


步骤四:创建itemView布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffff"
    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="@drawable/icon1" />

        <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="下午1:23"
                    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>


步骤五:创建RecycleView的Adapter

public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyViewHolder> {

    private List<Message> list;

    public RecycleViewAdapter(List<Message> list) {
        this.list = list;
    }

    class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView tv_username, tv_time, tv_message;
        private ImageView iv_icon;

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

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

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Message msg = list.get(position);
        holder.tv_username.setText(msg.getUsername());
        holder.tv_time.setText(msg.getTime());
        holder.tv_message.setText(msg.getMessage());
        holder.iv_icon.setBackgroundResource(msg.getImg_id());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }
}
思路分析: 这里的实现的形式跟ListView有点不一样,它继承的不是BaseAdapter,继承的是RecycleView的Adapter,并且泛型填一个ViewHolder,这个ViewHolder在该类中作为内部类实现,其他的实现跟ListView是一样的

步骤六:代码中使用

public class MainActivity extends AppCompatActivity {

    private RecyclerView rv;
    private RecycleViewAdapter adapter;
    private List<Message> list;

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

        initData();

        rv = (RecyclerView) findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(this));
        adapter = new RecycleViewAdapter(list);
        rv.setAdapter(adapter);
    }

    private void initData() {
        list = new ArrayList<>();
        list.add(new Message("Hensen", "下午1:22", "老板:哈哈哈", R.drawable.icon1));
        list.add(new Message("流年不利", "早上10:31", "美女:呵呵哒", R.drawable.icon2));
        list.add(new Message("1402", "下午1:55", "嘻嘻哈哈", R.drawable.icon3));
        list.add(new Message("Unstoppable", "下午4:32", "美美哒", R.drawable.icon4));
        list.add(new Message("流年不利", "晚上7:22", "萌萌哒", R.drawable.icon2));
        list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));
        list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));
        list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));
    }
}
和ListView不同的是,这里必须写这一句,不然View显示不出来,也是这一句话可以控制布局为LinearLayout或者是GridView或者是瀑布流布局

rv.setLayoutManager(new LinearLayoutManager(this));


步骤七:为recyclerView绑定触摸事件,这里就是我们效果实现的全部代码所在

        //为RecycleView绑定触摸事件
        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(list,viewHolder.getAdapterPosition(),target.getAdapterPosition());
                adapter.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());
                return false;
            }

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

            @Override
            public boolean isLongPressDragEnabled() {
                //是否可拖拽
                return true;
            }
        });
        helper.attachToRecyclerView(rv);
思路分析:我们规定拖拽的动作是上下拖拽,而删除效果是左右删除。在拖拽事件中,就是通过集合的一个交换然后实现布局的更新,这里RecyclerView的adapter都帮我们实现好了,用起来很简单,而删除事件就是集合删除一个数据,然后更新布局。


如果要实现效果二,可以做出类似桌面拖拽排序的效果,这个就请大家自由发挥吧,实现效果二,只要在效果一的基础上修改两处代码即可:

//        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setLayoutManager(new GridLayoutManager(this,2));
//首先回调的方法 返回int表示是否监听该方向
                int dragFlags = ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;//拖拽
                int swipeFlags = 0;//侧滑删除
                return makeMovementFlags(dragFlags,swipeFlags);


当然还有一种瀑布流的效果,只需在效果二的基础上修改一处代码即可,如果要实现更复杂的效果,可以自行百度:

//        rv.setLayoutManager(new GridLayoutManager(this,2));
        rv.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));


源码是AndroidStudio的Module,建议用Import Module导入源码下载









你可能感兴趣的:(android,控件,RecyclerView)