使用ItemTouchHelper实现RecyclerView
本篇文章我们来使用ItemTouchHelper实现RecyclerView Item的滑动删除。
先看一下关于ItemTouchHelper官方文档解释:
This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
ItemTouchHelper是一个用于在RecyclerView中实现滑动删除和拖拽的工具类。
在Module中使用RecyclerView,需要修改build.gradle文件,添加依赖。
// RecyclerView
implementation 'com.android.support:recyclerview-v7:28.0.0'
然后数据类型,People.java
/**
* 作者 yunyang
* 时间 2018/11/7 17:39
* 文件 RecyclerViewDemo
* 描述 实体类
*/
public class People {
private String profile;
public People(String profile) {
this.profile = profile;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
}
RecyclerView的适配器,DataProfileAdapter.java
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.TextView;
import com.maigu.yang.itemtouchremove.R;
import com.maigu.yang.itemtouchremove.entity.People;
import java.util.List;
/**
* 作者 yunyang
* 时间 2018/11/7 17:37
* 文件 RecyclerViewDemo
* 描述 适配器
*/
public class DataProfileAdapter extends RecyclerView.Adapter<DataProfileAdapter.MyHolder> {
private List<People> mList;
private Context mContext;
public DataProfileAdapter(Context context, List<People> list) {
mContext = context;
mList = list;
}
@NonNull
@Override
public MyHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(mContext).inflate(R.layout.item_profile, viewGroup, false);
return new MyHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyHolder myHolder, int i) {
myHolder.profile.setText(mList.get(i).getProfile());
}
@Override
public int getItemCount() {
return mList.size();
}
static class MyHolder extends RecyclerView.ViewHolder {
TextView profile;
MyHolder(View view) {
super(view);
profile = (TextView) view.findViewById(R.id.item_text_profile);
}
}
public void remove(int position) {
mList.remove(position);
notifyItemRemoved(position);
}
}
Item项的item_profile.xml布局文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<TextView
android:id="@+id/item_text_profile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:ellipsize="end"
android:gravity="center_vertical"
android:textColor="@color/colorAccent"
android:textSize="18sp" />
</LinearLayout>
构建好了实体类People和DataProfileAdapter,在构建DataProfileAdapter时,需要添加一个方法。也就是移除时,刷新RecyclerView适配器(Adapter)的列表。
public void remove(int position) {
mList.remove(position);
notifyItemRemoved(position);
}
在这里为了处理拖动和滑动事件,需要创建ItemTouchHelper.SimpleCallback的实现类。MovieItemTouchHelper.java
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import com.maigu.yang.itemtouchremove.adapter.DataProfileAdapter;
/**
* 作者 yunyang
* 时间 2018/11/7 17:53
* 文件 RecyclerViewDemo
* 描述 为了处理拖动和滑动事件,需要创建ItemTouchHelper.SimpleCallback的实现类。
*/
public class MovieItemTouchHelper extends ItemTouchHelper.SimpleCallback {
private DataProfileAdapter adapter;
public MovieItemTouchHelper(DataProfileAdapter adapter) {
super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
this.adapter = adapter;
}
/**
* If you don't support drag & drop, this method will never be called.
* 如果不支持拖拽,那么这个方法就不会被执行。
*
* @param recyclerView The RecyclerView to which ItemTouchHelper is attached to. ItemTouchHelper需要附加到的RecyclerView
* @param viewHolder The ViewHolder which is being dragged by the user. 拖动的ViewHolder
* @param target The ViewHolder over which the currently active item is being dragged. 目标位置的ViewHolder
* @return True if the viewHolder has been moved to the adapter position of target. viewHolder是否被移动到目标位置
*/
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
/**
* Called when a ViewHolder is swiped by the user.
* If you don't support swiping, this method will never be called.
* 如果不支持滑动,方法不会被执行。
*
* @param viewHolder The ViewHolder which has been swiped by the user.
* @param direction The direction to which the ViewHolder is swiped.
* It is one of UP, DOWN, LEFT or RIGHT.
* If your getMovementFlags(RecyclerView, ViewHolder) method returned relative flags instead of LEFT / RIGHT;
* `direction` will be relative as well. (START or END).
*/
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//Remove item
adapter.remove(viewHolder.getAdapterPosition());
}
}
MovieItemTouchHelper默认的构造方法需要传入两个参数。
/**
* Creates a Callback for the given drag and swipe allowance.
* @param dragDirs 表示拖拽的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
* @param swipeDirs 表示滑动的方向,有六个类型的值:LEFT、RIGHT、START、END、UP、DOWN
*/
ItemTouchHelper.SimpleCallback(int dragDirs, int swipeDirs)
MovieItemTouchHelper默认需要实现两个方法onMove(),onSwiped(),
- onMove()是对拖拽的实现
- onSwiped()是对滑动的实现
最后将创建完毕的MovieItemTouchHelper附加到RecyclerView类上即可使用滑动删除功能。
查看MainActivity.java文件。
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 com.maigu.yang.itemtouchremove.adapter.DataProfileAdapter;
import com.maigu.yang.itemtouchremove.entity.People;
import com.maigu.yang.itemtouchremove.utils.MovieItemTouchHelper;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private DataProfileAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initRecy();
}
private void initRecy() {
LinearLayoutManager manager = new LinearLayoutManager(this);
mAdapter = new DataProfileAdapter(this, Data());
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setAdapter(mAdapter);
ItemTouchHelper.Callback callback = new MovieItemTouchHelper(mAdapter);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(mRecyclerView);
}
private List<People> Data() {
List<People> mPeople = new ArrayList<>();
for (int i = 0; i < 50; i++) {
mPeople.add(new People("暖暖的云阳 始终唯一,不为所动。 " + i));
}
return mPeople;
}
private void initView() {
mRecyclerView = (RecyclerView) findViewById(R.id.recy_index);
}
}
主要在initRecy方法中,这三方关键代码,调用滑动删除功能。
ItemTouchHelper.Callback callback = new MovieItemTouchHelper(mAdapter);
ItemTouchHelper helper = new ItemTouchHelper(callback);
helper.attachToRecyclerView(mRecyclerView);
接下来看一下MainActivity的布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recy_index"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
最后是测试结果图演示
效果图.gif