一.简介
从Android 5.0开始,谷歌推出了新的控件RecyclerView,用它来代替之前的ListView,优点多多,功能强大,也给我们的开发着提供了极大的便利。下面讲解一下RecyclerView轻松实现滑动删除及拖拽的效果。
RecyclerView实现滑动和拖拽效果相比较ListView要简单的多,因为谷歌给我们提供了强大的工具类ItemTouchHelper,它已经处理了关于RecyclerView拖动和滑动的实现,并且我们可以在其中实现我们自己的动画,以及定制我们想要的效果。
二.详解
ItemTouchHelper工具类有一个叫CallBack的内部静态类。
public abstract static class Callback
RecyclerView拖动的实现就是要继承这个内部静态类。
package com.wjn.viewlistdemo.activity.recyclerview;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
public class RecycleItemTouchHelper extends ItemTouchHelper.Callback {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
return 0;
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
}
}
可知,继承ItemTouchHelper.Callback必须实现的方法有三个,下面一一讲解。
1.getMovementFlags方法
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder)
该方法返回一个整数,用来指定拖拽和滑动在哪个方向是被允许的。在该方法中使用makeMovementFlags(int dragFlags, int swipeFlags)返回,该方法第一个参数用来指定拖动,第二个参数用来指定滑动。对于方向参数有6种
ItemTouchHelper.UP //滑动拖拽向上方向
ItemTouchHelper.DOWN//向下
ItemTouchHelper.LEFT//向左
ItemTouchHelper.RIGHT//向右
ItemTouchHelper.START//依赖布局方向的水平开始方向
ItemTouchHelper.END//依赖布局方向的水平结束方向
注意,使用时可组合使用用“|”隔开,比如
return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN,ItemTouchHelper.END );
2.onMove方法
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1)
该方法是拖拽的回调。
参数 RecyclerView.ViewHolder viewHolder 是拖动的Item。
参数 RecyclerView.ViewHolder viewHolder1 是拖动的目标位置的Item。
该方法如果返回true表示切换了位置,反之返回false。
3.onSwiped方法
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i)
该方法为Item滑动回调。
参数 viewHolder为滑动的item。
参数 i 为滑动的方向。
以上三个方法是继承ItemTouchHelper.Callback类必须实现的三个方法,其实ItemTouchHelper.Callback类还有很多个方法。比如常用的几个。
4.isLongPressDragEnabled方法
public boolean isLongPressDragEnabled()
Item是否支持长按拖动。
true 支持长按操作。
false 不支持长按操作。
5.isItemViewSwipeEnabled方法
public boolean isItemViewSwipeEnabled()
Item是否支持滑动。
true 支持滑动操作。
false 不支持滑动操作。
注意:如果我们想实现拖动,该方法必须返回true,否则onMove或者onSwiped方法不会执行。
6.onChildDraw方法
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
移动过程中绘制Item。
参数 Canvas c 画布
参数 RecyclerView recyclerView RecyclerView对象
参数 RecyclerView.ViewHolder viewHolder ViewHolder对象
参数 float dX X轴移动的距离
参数 float dY Y轴移动的距离
参数 int actionState 当前Item的状态
参数 boolean isCurrentlyActive 如果当前被用户操作为true,反之为false
7.onSelectedChanged方法
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState)
Item被选中时候回调。
参数 RecyclerView.ViewHolder viewHolder ViewHolder对象
参数 int actionState 当前Item的状态
(1) temTouchHelper.ACTION_STATE_IDLE 闲置状态。
(2) ItemTouchHelper.ACTION_STATE_SWIPE 滑动中状态。
(3) ItemTouchHelper#ACTION_STATE_DRAG 拖拽中状态。
三.代码实现
接口
package com.wjn.viewlistdemo.activity.recyclerview.slide;
import android.view.View;
public interface ItemClickCallBack {
void onItemCilck(View view, int position);
}
package com.wjn.viewlistdemo.activity.recyclerview.slide;
public interface ItemSlideCallBack {
void onMove(int fromPosition, int toPosition);
}
2. Adapter
package com.wjn.viewlistdemo.activity.recyclerview.slide;
import android.content.Context;
import android.support.annotation.NonNull;
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 com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import java.util.Collections;
import java.util.List;
public class SlideAdapter extends RecyclerView.Adapter<SlideAdapter.ViewHolder> implements ItemSlideCallBack {
private List<Student> list;
private LayoutInflater mInflater;
private ItemClickCallBack itemClickCallBack = null;
public void setItemClickCallBack(ItemClickCallBack mItemClickCallBack) {
itemClickCallBack = mItemClickCallBack;
}
public SlideAdapter(Context context, List<Student> list) {
this.list = list;
mInflater = LayoutInflater.from(context);
}
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = mInflater.inflate(R.layout.recyclerview_item, viewGroup, false);
SlideAdapter.ViewHolder holder = new SlideAdapter.ViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
viewHolder.textView1.setText(list.get(i).getName() + "【" + (i + 1) + "】");
viewHolder.textView2.setText(list.get(i).getDescribe());
viewHolder.circleImageView.setBackgroundResource(R.mipmap.patient_ava);
/**
* 捕获RecycleView的Item点击
* */
final int clickposition = i;
//Item点击
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != itemClickCallBack) {
itemClickCallBack.onItemCilck(v, clickposition);
}
}
});
}
@Override
public int getItemCount() {
return list.size();
}
/**
* ViewHolder类
*/
class ViewHolder extends RecyclerView.ViewHolder {
private ImageView circleImageView;
private TextView textView1;
private TextView textView2;
public ViewHolder(View itemView) {
super(itemView);
circleImageView = itemView.findViewById(R.id.recycleview_circleimageview);
textView1 = itemView.findViewById(R.id.recycleview_item_textview1);
textView2 = itemView.findViewById(R.id.recycleview_item_textview2);
}
}
/**
* 交换数据
*/
@Override
public void onMove(int fromPosition, int toPosition) {
Collections.swap(list, fromPosition, toPosition);//交换数据
notifyItemMoved(fromPosition, toPosition);
notifyItemChanged(fromPosition);
notifyItemChanged(toPosition);
}
}
3. ItemTouchHelper.Callback
package com.wjn.viewlistdemo.activity.recyclerview.slide;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
public class SlideItemTouchHelper extends ItemTouchHelper.Callback {
private ItemSlideCallBack itemSlideCallBack;
public SlideItemTouchHelper(ItemSlideCallBack mItemSlideCallBack) {
itemSlideCallBack = mItemSlideCallBack;
}
/**
* 设置滑动类型标记
*/
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.END);
}
/**
* 拖拽交换Item的回调
*/
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder viewHolder1) {
if (null != itemSlideCallBack) {
itemSlideCallBack.onMove(viewHolder.getAdapterPosition(), viewHolder1.getAdapterPosition());
}
return true;
}
/**
* 滑动Item
*/
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
}
}
4.使用
package com.wjn.viewlistdemo.activity.recyclerview.slide;
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 android.view.View;
import android.widget.Toast;
import com.wjn.viewlistdemo.R;
import com.wjn.viewlistdemo.activity.recyclerview.RecyclerViewUtils;
import com.wjn.viewlistdemo.activity.recyclerview.Student;
import java.util.List;
public class RecyclerViewSlideActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<Student> list;
private SlideAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerviewslide);
initView();
}
/**
* 初始化各种View
*/
private void initView() {
recyclerView = findViewById(R.id.activity_recyclerviewslide_recycleview);
list = RecyclerViewUtils.getInstance().getList();
//1.设置LinearLayoutManager ListView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//2.设置固定大小
recyclerView.setHasFixedSize(true);
//3.设置Adapter
adapter = new SlideAdapter(this, list);
recyclerView.setAdapter(adapter);
//4.设置 ItemTouchHelper.Callback
ItemTouchHelper.Callback callback = new SlideItemTouchHelper(adapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(recyclerView);
//5.设置RecyclerView Item各种Action
setRecycleViewItemAction();
}
/**
* 设置RecyclerView Item各种Action Item点击
*/
private void setRecycleViewItemAction() {
if (adapter == null) {
return;
}
adapter.setItemClickCallBack(new ItemClickCallBack() {
@Override
public void onItemCilck(View view, int position) {
if (null != list) {
String name = list.get(position).getName();
Toast.makeText(RecyclerViewSlideActivity.this, "点击了:" + name + " Position:" + position, Toast.LENGTH_SHORT).show();
}
}
});
}
}