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>
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; } }
<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));
//为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导入源码下载