📌  相关文章
📜  Android 创建滑动删除RecyclerView的项目

📅  最后修改于: 2020-10-11 05:53:08             🧑  作者: Mango

Android滑动以使用UNDU删除RecyclerView项目

在本教程中,我们将创建示例以通过使用撤消功能滑动项目来删除RecyclerView的项目。为此,我们将使用Android支持库V7中添加的ItemTouchHelper类。此类用于创建滑动以删除RecyclerView的项目。它具有SimpleCallback类,该类可配置为滑动或移动RecyclerView的项目而执行的事件。

ItemTouchHelper类

这是一个实用程序类,它提供添加滑动以消除和拖放RecyclerView项的功能。根据我们实现的功能,它会覆盖回调方法onMove()或onSwipe()。

Android轻扫以删除RecyclerView项目示例

使用以下代码创建MainActivity.java类。

activity_main.xml

ass with the following code.
activity_main.xml



    

        

    

    



content_main.xml


MainActivity.java

package example.javatpoint.com.recyclerviewswipedeleteundo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

    }
}

创建一个布局normal_item.xml,它以正常模式显示。

Regular_item.xml




    

创建一个布局swipe_item.xml,该布局出现在滑动项目期间。

swipe_item.xml




    


    


customlayout.xml



    
    
    
    

创建一个实用程序类SwipeUtil.java,该类扩展了ItemTouchHelper.SimpleCallback类并覆盖其onMove(),onSwiped(),onChildDraw()方法。当我们对某个项目执行滑动操作时,将调用onSwiped()方法,并且onChildDraw()方法包含在滑动RecyclerView的项目时绘制画布的实现逻辑。

SwipeUtil.java

package example.javatpoint.com.recyclerviewswipedeleteundo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;

public abstract class SwipeUtil extends ItemTouchHelper.SimpleCallback {

    private Drawable background;
    private Drawable deleteIcon;
    private int xMarkMargin;
    private boolean initiated;
    private Context context;
    private int leftcolorCode;
    private String leftSwipeLable;

    public SwipeUtil(int dragDirs, int swipeDirs, Context context) {
        super(dragDirs, swipeDirs);
        this.context = context;
    }

    private void init() {
        background = new ColorDrawable();
        xMarkMargin = (int) context.getResources().getDimension(R.dimen.ic_clear_margin);
        deleteIcon = ContextCompat.getDrawable(context, android.R.drawable.ic_menu_delete);
        deleteIcon.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
        initiated = true;
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public abstract void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);

    @Override
    public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {

        return super.getSwipeDirs(recyclerView, viewHolder);
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
                            float dX, float dY, int actionState, boolean isCurrentlyActive) {

        View itemView = viewHolder.itemView;
        if (!initiated) {
            init();
        }

        int itemHeight = itemView.getBottom() - itemView.getTop();
        //Setting Swipe Background
        ((ColorDrawable) background).setColor(getLeftcolorCode());
        background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
        background.draw(c);

        int intrinsicWidth = deleteIcon.getIntrinsicWidth();
        int intrinsicHeight = deleteIcon.getIntrinsicWidth();

        int xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth;
        int xMarkRight = itemView.getRight() - xMarkMargin;
        int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
        int xMarkBottom = xMarkTop + intrinsicHeight;

        //Setting Swipe Icon
        deleteIcon.setBounds(xMarkLeft, xMarkTop + 16, xMarkRight, xMarkBottom);
        deleteIcon.draw(c);

        //Setting Swipe Text
        Paint paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setTextSize(48);
        paint.setTextAlign(Paint.Align.CENTER);
        c.drawText(getLeftSwipeLable(), xMarkLeft + 40, xMarkTop + 10, paint);

        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }

    public String getLeftSwipeLable() {
        return leftSwipeLable;
    }

    public void setLeftSwipeLable(String leftSwipeLable) {
        this.leftSwipeLable = leftSwipeLable;
    }

    public int getLeftcolorCode() {
        return leftcolorCode;
    }

    public void setLeftcolorCode(int leftcolorCode) {
        this.leftcolorCode = leftcolorCode;
    }
}

创建一个ItemViewHolder.java类,并扩展RecyclerView.ViewHolder。

ItemViewHolder.java

package example.javatpoint.com.recyclerviewswipedeleteundo;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class ItemViewHolder extends RecyclerView.ViewHolder {

    public LinearLayout regularLayout;
    public LinearLayout swipeLayout;
    public TextView listItem;
    public TextView undo;

    public ItemViewHolder(View view) {
        super(view);

        regularLayout = view.findViewById(R.id.regularLayout);
        listItem =  view.findViewById(R.id.list_item);
        swipeLayout = view.findViewById(R.id.swipeLayout);
        undo =  view.findViewById(R.id.undo);
    }
}

创建一个适配器类MyAdapter.java,它扩展了RecyclerView.Adapter类并覆盖其onCreateViewHolder(),onBindViewHolder()方法。

MyAdapter.java

package example.javatpoint.com.recyclerviewswipedeleteundo;

import android.os.Handler;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MyAdapter extends RecyclerView.Adapter {

    private List dataList;
    private List itemsPendingRemoval;

    private static final int PENDING_REMOVAL_TIMEOUT = 3000; // 3sec
    private Handler handler = new Handler(); // hanlder for running delayed runnables
    HashMap pendingRunnables = new HashMap<>(); // map of items to pending runnable, to cancel the removal


    public MyAdapter(List dataList) {
        this.dataList = dataList;
        itemsPendingRemoval = new ArrayList<>();
    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.customlayout, parent, false);
        return new ItemViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ItemViewHolder itemViewHolder, int position) {

        final String data = dataList.get(position);

        if (itemsPendingRemoval.contains(data)) {
            /** show swipe layout and hide regular layout */
            itemViewHolder.regularLayout.setVisibility(View.GONE);
            itemViewHolder.swipeLayout.setVisibility(View.VISIBLE);
            itemViewHolder.undo.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    undoOpt(data);
                }
            });
        } else {
            /** show regular layout and hide swipe layout*/
            itemViewHolder.regularLayout.setVisibility(View.VISIBLE);
            itemViewHolder.swipeLayout.setVisibility(View.GONE);
            itemViewHolder.listItem.setText(data);
        }
    }

    private void undoOpt(String customer) {
        Runnable pendingRemovalRunnable = pendingRunnables.get(customer);
        pendingRunnables.remove(customer);
        if (pendingRemovalRunnable != null)
            handler.removeCallbacks(pendingRemovalRunnable);
        itemsPendingRemoval.remove(customer);
        // this will rebind the row in "normal" state
        notifyItemChanged(dataList.indexOf(customer));
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    public void pendingRemoval(int position) {

        final String data = dataList.get(position);
        if (!itemsPendingRemoval.contains(data)) {
            itemsPendingRemoval.add(data);
            // this will redraw row in "undo" state
            notifyItemChanged(position);
            //create, store and post a runnable to remove the data
            Runnable pendingRemovalRunnable = new Runnable() {
                @Override
                public void run() {
                    remove(dataList.indexOf(data));
                }
            };
            handler.postDelayed(pendingRemovalRunnable, PENDING_REMOVAL_TIMEOUT);
            pendingRunnables.put(data, pendingRemovalRunnable);
        }
    }

    public void remove(int position) {
        String data = dataList.get(position);
        if (itemsPendingRemoval.contains(data)) {
            itemsPendingRemoval.remove(data);
        }
        if (dataList.contains(data)) {
            dataList.remove(position);
            notifyItemRemoved(position);
        }
    }

    public boolean isPendingRemoval(int position) {
        String data = dataList.get(position);
        return itemsPendingRemoval.contains(data);
    }
}

创建一个MainActivityFragment.java类并扩展Fragment类。在此类中,设置适配器MyAdapter.java类和实用程序SwipeUtil.java类。

fragment_main.xml



    

MainActivityFragment.java

package example.javatpoint.com.recyclerviewswipedeleteundo;

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;

public class MainActivityFragment extends Fragment {

    private RecyclerView mRecyclerView;
    private MyAdapter myAdapter;
    String[] listValue = {"C Tutorial","C++ Tutorial","Data Structure","Java Tutorial","Android Example","Kotlin Programing","Python language","Ruby Tutorial",".Net Tutorial","MySQL Database"};
    public MainActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View mView = inflater.inflate(R.layout.fragment_main, container, false);
        mRecyclerView = mView.findViewById(R.id.recyclerView);
        return mView;
    }

    @Override
    public void onResume() {
        super.onResume();
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        myAdapter = new MyAdapter(getData());
        mRecyclerView.setAdapter(myAdapter);

        setSwipeForRecyclerView();
    }

    private List getData() {
        List modelList = new ArrayList<>();
        for (int i = 0; i < listValue.length; i++) {
            modelList.add(listValue[i]);
        }
        return modelList;
    }

    private void setSwipeForRecyclerView() {

        SwipeUtil swipeHelper = new SwipeUtil(0, ItemTouchHelper.LEFT, getActivity()) {
            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                int swipedPosition = viewHolder.getAdapterPosition();
                myAdapter = (MyAdapter)mRecyclerView.getAdapter();
                myAdapter.pendingRemoval(swipedPosition);
            }

            @Override
            public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
                int position = viewHolder.getAdapterPosition();
                myAdapter = (MyAdapter) mRecyclerView.getAdapter();
               if (myAdapter.isPendingRemoval(position)) {
                     return 0;
                }
                return super.getSwipeDirs(recyclerView, viewHolder);
            }
        };

        ItemTouchHelper mItemTouchHelper = new ItemTouchHelper(swipeHelper);
        mItemTouchHelper.attachToRecyclerView(mRecyclerView);
        //set swipe label
        swipeHelper.setLeftSwipeLable("Archive");
        //set swipe background-Color
        swipeHelper.setLeftcolorCode(ContextCompat.getColor(getActivity(), R.color.swipebackground));
    }
}

strings.xml


    RecyclerView SwipeDeleteUndo
    Settings
    Hello blank fragment
    Undo
    Archive

dimens.xml


    16dp
    16dp
    16dp
    56dp
    20sp

colors.xml



    #3F51B5
    #303F9F
    #FF4081
    #cf0b4e

输出: