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

 

[java] view plain copy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#F4F4F3"  
  6.     android:orientation="vertical"  
  7.     tools:context="com.handsome.app3.MainActivity">  
  8.   
  9.     <ImageView  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:background="@drawable/top" />  
  13.   
  14.     <android.support.v7.widget.RecyclerView  
  15.         android:id="@+id/rv"  
  16.         android:layout_width="match_parent"  
  17.         android:layout_height="match_parent"  
  18.         android:layout_weight="1" />  
  19.   
  20.     <ImageView  
  21.         android:layout_width="match_parent"  
  22.         android:layout_height="wrap_content"  
  23.         android:background="@drawable/bottom" />  
  24. </LinearLayout>  


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

 

 

[java] view plain copy
 
  1. public class Message {  
  2.   
  3.     private String username;  
  4.     private String time;  
  5.     private String message;  
  6.     private int img_id;  
  7.   
  8.     public Message(String username, String time, String message, int img_id) {  
  9.         this.username = username;  
  10.         this.time = time;  
  11.         this.message = message;  
  12.         this.img_id = img_id;  
  13.     }  
  14.   
  15.     public String getUsername() {  
  16.         return username;  
  17.     }  
  18.   
  19.     public void setUsername(String username) {  
  20.         this.username = username;  
  21.     }  
  22.   
  23.     public String getTime() {  
  24.         return time;  
  25.     }  
  26.   
  27.     public void setTime(String time) {  
  28.         this.time = time;  
  29.     }  
  30.   
  31.     public String getMessage() {  
  32.         return message;  
  33.     }  
  34.   
  35.     public void setMessage(String message) {  
  36.         this.message = message;  
  37.     }  
  38.   
  39.     public int getImg_id() {  
  40.         return img_id;  
  41.     }  
  42.   
  43.     public void setImg_id(int img_id) {  
  44.         this.img_id = img_id;  
  45.     }  
  46. }  

 

 

步骤四:创建itemView布局

 

[java] view plain copy
 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:layout_width="match_parent"  
  3.     android:layout_height="wrap_content"  
  4.     android:background="#ffffff"  
  5.     android:orientation="vertical">  
  6.   
  7.     <LinearLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:orientation="horizontal"  
  11.         android:padding="8dp">  
  12.   
  13.         <ImageView  
  14.             android:id="@+id/iv_icon"  
  15.             android:layout_width="50dp"  
  16.             android:layout_height="50dp"  
  17.             android:background="@drawable/icon1" />  
  18.   
  19.         <LinearLayout  
  20.             android:layout_width="match_parent"  
  21.             android:layout_height="wrap_content"  
  22.             android:orientation="vertical">  
  23.   
  24.             <LinearLayout  
  25.                 android:layout_width="match_parent"  
  26.                 android:layout_height="wrap_content"  
  27.                 android:orientation="horizontal"  
  28.                 android:padding="4dp">  
  29.   
  30.                 <TextView  
  31.                     android:id="@+id/tv_username"  
  32.                     android:layout_width="wrap_content"  
  33.                     android:layout_height="wrap_content"  
  34.                     android:layout_marginLeft="4dp"  
  35.                     android:layout_weight="1"  
  36.                     android:text="夜雨"  
  37.                     android:textColor="#000000"  
  38.                     android:textSize="16dp" />  
  39.   
  40.                 <TextView  
  41.                     android:id="@+id/tv_time"  
  42.                     android:layout_width="wrap_content"  
  43.                     android:layout_height="wrap_content"  
  44.                     android:text="下午1:23"  
  45.                     android:textColor="#888888"  
  46.                     android:textSize="14dp" />  
  47.   
  48.             </LinearLayout>  
  49.   
  50.             <LinearLayout  
  51.                 android:layout_width="match_parent"  
  52.                 android:layout_height="wrap_content"  
  53.                 android:orientation="horizontal"  
  54.                 android:paddingLeft="4dp">  
  55.   
  56.                 <TextView  
  57.                     android:id="@+id/tv_message"  
  58.                     android:layout_width="wrap_content"  
  59.                     android:layout_height="wrap_content"  
  60.                     android:layout_marginLeft="4dp"  
  61.                     android:text="你好啊"  
  62.                     android:textColor="#888888"  
  63.                     android:textSize="14dp" />  
  64.             </LinearLayout>  
  65.         </LinearLayout>  
  66.     </LinearLayout>  
  67. </LinearLayout>  

 

 

步骤五:创建RecycleView的Adapter

 

[java] view plain copy
 
  1. public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyViewHolder> {  
  2.   
  3.     private List<Message> list;  
  4.   
  5.     public RecycleViewAdapter(List<Message> list) {  
  6.         this.list = list;  
  7.     }  
  8.   
  9.     class MyViewHolder extends RecyclerView.ViewHolder {  
  10.         private TextView tv_username, tv_time, tv_message;  
  11.         private ImageView iv_icon;  
  12.   
  13.         public MyViewHolder(View itemView) {  
  14.             super(itemView);  
  15.             tv_username = (TextView) itemView.findViewById(R.id.tv_username);  
  16.             tv_time = (TextView) itemView.findViewById(R.id.tv_time);  
  17.             tv_message = (TextView) itemView.findViewById(R.id.tv_message);  
  18.             iv_icon = (ImageView) itemView.findViewById(R.id.iv_icon);  
  19.         }  
  20.     }  
  21.   
  22.     @Override  
  23.     public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  24.         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item, parent, false);  
  25.         return new MyViewHolder(view);  
  26.     }  
  27.   
  28.     @Override  
  29.     public void onBindViewHolder(MyViewHolder holder, int position) {  
  30.         Message msg = list.get(position);  
  31.         holder.tv_username.setText(msg.getUsername());  
  32.         holder.tv_time.setText(msg.getTime());  
  33.         holder.tv_message.setText(msg.getMessage());  
  34.         holder.iv_icon.setBackgroundResource(msg.getImg_id());  
  35.     }  
  36.   
  37.     @Override  
  38.     public int getItemCount() {  
  39.         return list.size();  
  40.     }  
  41. }  

思路分析:这里的实现的形式跟ListView有点不一样,它继承的不是BaseAdapter,继承的是RecycleView的Adapter,并且泛型填一个ViewHolder,这个ViewHolder在该类中作为内部类实现,其他的实现跟ListView是一样的

 

步骤六:代码中使用

 

[java] view plain copy
 
  1. public class MainActivity extends AppCompatActivity {  
  2.   
  3.     private RecyclerView rv;  
  4.     private RecycleViewAdapter adapter;  
  5.     private List<Message> list;  
  6.   
  7.     @Override  
  8.     protected void onCreate(Bundle savedInstanceState) {  
  9.         super.onCreate(savedInstanceState);  
  10.         setContentView(R.layout.activity_main);  
  11.   
  12.         initData();  
  13.   
  14.         rv = (RecyclerView) findViewById(R.id.rv);  
  15.         rv.setLayoutManager(new LinearLayoutManager(this));  
  16.         adapter = new RecycleViewAdapter(list);  
  17.         rv.setAdapter(adapter);  
  18.     }  
  19.   
  20.     private void initData() {  
  21.         list = new ArrayList<>();  
  22.         list.add(new Message("Hensen", "下午1:22", "老板:哈哈哈", R.drawable.icon1));  
  23.         list.add(new Message("流年不利", "早上10:31", "美女:呵呵哒", R.drawable.icon2));  
  24.         list.add(new Message("1402", "下午1:55", "嘻嘻哈哈", R.drawable.icon3));  
  25.         list.add(new Message("Unstoppable", "下午4:32", "美美哒", R.drawable.icon4));  
  26.         list.add(new Message("流年不利", "晚上7:22", "萌萌哒", R.drawable.icon2));  
  27.         list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));  
  28.         list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));  
  29.         list.add(new Message("Hensen", "下午1:22", "哈哈哈", R.drawable.icon1));  
  30.     }  
  31. }  

和ListView不同的是,这里必须写这一句,不然View显示不出来,也是这一句话可以控制布局为LinearLayout或者是GridView或者是瀑布流布局

 

 

[java] view plain copy
 
  1. rv.setLayoutManager(new LinearLayoutManager(this));  

 

 

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

 

[java] view plain copy
 
  1. //为RecycleView绑定触摸事件  
  2. ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {  
  3.     @Override  
  4.     public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {  
  5.         //首先回调的方法 返回int表示是否监听该方向  
  6.         int dragFlags = ItemTouchHelper.UP|ItemTouchHelper.DOWN;//拖拽  
  7.         int swipeFlags = ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT;//侧滑删除  
  8.         return makeMovementFlags(dragFlags,swipeFlags);  
  9.     }  
  10.   
  11.     @Override  
  12.     public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {  
  13.         //滑动事件  
  14.         Collections.swap(list,viewHolder.getAdapterPosition(),target.getAdapterPosition());  
  15.         adapter.notifyItemMoved(viewHolder.getAdapterPosition(),target.getAdapterPosition());  
  16.         return false;  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {  
  21.         //侧滑事件  
  22.         list.remove(viewHolder.getAdapterPosition());  
  23.         adapter.notifyItemRemoved(viewHolder.getAdapterPosition());  
  24.     }  
  25.   
  26.     @Override  
  27.     public boolean isLongPressDragEnabled() {  
  28.         //是否可拖拽  
  29.         return true;  
  30.     }  
  31. });  
  32. helper.attachToRecyclerView(rv);  

思路分析:我们规定拖拽的动作是上下拖拽,而删除效果是左右删除。在拖拽事件中,就是通过集合的一个交换然后实现布局的更新,这里RecyclerView的adapter都帮我们实现好了,用起来很简单,而删除事件就是集合删除一个数据,然后更新布局。

 

 

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

 

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

 

 

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

 

[java] view plain copy
 
  1. //        rv.setLayoutManager(new GridLayoutManager(this,2));  
  2.         rv.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL));  

 

 

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

posted @ 2016-12-30 16:20  天涯海角路  阅读(575)  评论(0)    收藏  举报