1. 程式人生 > >使用ItemTouchHelper實現RecyclerView Item的滑動刪除

使用ItemTouchHelper實現RecyclerView Item的滑動刪除

本篇文章我們來使用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>

最後是測試結果圖演示
效果圖