简体   繁体   English

RecyclerView 为列表中的每个项目使用不同的 ItemTouchHelper

[英]RecyclerView with different ItemTouchHelper for each item on the list

I'm trying to implement a Recycleview with different ItemTouchHelper for each item on the list.我正在尝试为列表中的每个项目实现一个具有不同 ItemTouchHelper 的 Recycleview。

The only way that I know is to add an ItemTouchHelper directly to the RecycleView and not to the item.我知道的唯一方法是将 ItemTouchHelper 直接添加到 RecycleView 而不是项目。

Example of what I'm trying to do:我正在尝试做的示例:

I have a list with 4 items and all items I can swipe to the left.我有一个包含 4 个项目的列表,我可以向左滑动所有项目。

  • The first item will show a delete button.第一项将显示一个删除按钮。

  • The second item will show a delete button and edit button.第二项将显示删除按钮和编辑按钮。

  • The third item shows a delete button.第三项显示删除按钮。

  • The fourth item shows a copy, a delete, and an edit button.第四个项目显示复制、删除和编辑按钮。

*The list can have a lot of items. *列表可以有很多项目。

Does someone know how to do that?有人知道该怎么做吗?

The idea这个想法

So basically your your question is about how to add a unique ItemTouchHelper to each RecyclerView item based on the item type.所以基本上你的问题是关于如何根据项目类型为每个RecyclerView项目添加一个唯一的ItemTouchHelper

Without going deeply into the details of how you want each item to differ in the ItemTouchHelper swipe action, like you said to add some button functionalities like copy, edit, and delete.无需深入了解您希望每个项目如何在ItemTouchHelper滑动操作中有所不同的细节,就像您所说的添加一些按钮功能,如复制、编辑和删除。 I will be just to the point How to differ ItemTouchHelper 's swipe for different items.我将直接指出如何区分不同项目的ItemTouchHelper滑动。

Steps脚步

Step 1: Differentiate among RecyclerView items using a POJO field第 1 步:使用 POJO 字段区分RecyclerView项目

So, first you need to create a field in your POJO (typically an int or enum ) that differentiates among different items.因此,首先您需要在 POJO(通常是intenum )中创建一个区分不同项目的字段。

Step 2: Implement a custom ItemTouchHelper.SimpleCallback第 2 步:实现自定义ItemTouchHelper.SimpleCallback

Create a custom ItemTouchHelper.SimpleCallback class that takes the list of the RecyclerView items into its constructor.创建一个自定义ItemTouchHelper.SimpleCallback class ,它将RecyclerView项目的列表带入其构造函数。

Next, override onChildDraw() which is called by ItemTouchHelper on RecyclerView 's onDraw() callback;接下来,覆盖由onChildDraw()RecyclerViewonDraw()回调中调用的ItemTouchHelper (); and this is the right place as it's called whenever the RecyclerView draws its individual items.这是在 RecyclerView 绘制其单个项目时调用的正确位置。

So, in this method you can implement how you want each item looks like when you swipe.因此,在此方法中,您可以实现滑动时每个项目的外观。 And as it takes a ViewHolder instance, so you can get the swiped item position with ViewHolder.getAdapterPosition() , and from the provided list of items, you can get the swiped item of this paritcular positon.由于它需要一个 ViewHolder 实例,因此您可以使用ViewHolder.getAdapterPosition()获取滑动项目 position ,并且从提供的项目列表中,您可以获得此特定位置的滑动项目。

Example例子

Here is a simple example that is a list of colors that reflects the background color whenever you swipe a certain item.这是一个简单的示例,它是 colors 的列表,当您滑动某个项目时,它会反映背景颜色。

This is how it looks like:这是它的样子:

POJO POJO

For the above mentioned step 1, I store the value into colorValue field对于上述第 1 步,我将值存储到colorValue字段中

class ColorItem {

    String colorName;
    int colorValue;

    public ColorItem(String colorName, int colorValue) {
        this.colorName = colorName;
        this.colorValue = colorValue;
    }

    public String getColorName() {
        return colorName;
    }

    public void setColorName(String colorName) {
        this.colorName = colorName;
    }

    public int getColorValue() {
        return colorValue;
    }

    public void setColorValue(int colorValue) {
        this.colorValue = colorValue;
    }
}

RecyclerView adapter (no fancy code) RecyclerView 适配器(没有花哨的代码)

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.CustomViewHolder> {

    List<ColorItem> mColors;

    // Constructor
    RecyclerAdapter(List<ColorItem> colors) {
        this.mColors = colors;
    }

    @NonNull
    @Override
    public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
        View listItem = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);
        return new CustomViewHolder(listItem);
    }

    @Override
    public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
        holder.tvColorName.setText(mColors.get(position).getColorName());
    }

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

    class CustomViewHolder extends RecyclerView.ViewHolder implements {

        TextView tvColorName;

        CustomViewHolder(@NonNull View listItem) {
            super(listItem);
            tvColorName = listItem.findViewById(R.id.tvColorName);
        }

      
    }
}

Custom ItemTouchHelper.SimpleCallback自定义 ItemTouchHelper.SimpleCallback


public class ItemSwipeCallback extends ItemTouchHelper.SimpleCallback {

    private final List<ColorItem> mColorItems;
    private Context mContext;

    public interface OnTouchListener {
        void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);
    }

    private OnTouchListener mOnTouchListener;

    public ItemSwipeCallback(Context context, List<ColorItem> items, int dragDirs, int swipeDirs, OnTouchListener onTouchListener) {
        super(dragDirs, swipeDirs);
        mContext = context;
        mColorItems = items;
        mOnTouchListener = onTouchListener;
    }


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

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        mOnTouchListener.onSwiped(viewHolder, direction);
    }

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

        // Getting the swiped item
        ColorItem item = mColorItems.get(viewHolder.getAdapterPosition());

        // Get the color of the swiped item (the thing that differentiates among items)
        ColorDrawable background = new ColorDrawable(mContext.getResources().getColor(item.getColorValue()));

        // Changing the color of the background item
        View itemView = viewHolder.itemView;
        int backgroundCornerOffset = 25; //so mBackground is behind the rounded corners of itemView

        if (dX > 0) { // Swiping to the right
            background.setBounds(itemView.getLeft(), itemView.getTop(),
                    itemView.getLeft() + ((int) dX) + backgroundCornerOffset, itemView.getBottom());
        } else if (dX < 0) { // Swiping to the left
            background.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
                    itemView.getTop(), itemView.getRight(), itemView.getBottom());
        } else { // view is unSwiped
            background.setBounds(0, 0, 0, 0);
        }

        background.draw(c);

    }
}

Activity活动

public class MainActivity extends AppCompatActivity {

    ArrayList<ColorItem> mColors;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mColors = new ArrayList<>();
        populateColors();
        setupRecyclerView();

    }

    private void setupRecyclerView() {
        RecyclerAdapter adapter = new RecyclerAdapter(this, mColors);
        RecyclerView recyclerview = findViewById(R.id.recyclerview);
        RecyclerView.LayoutManager layoutMgr = new LinearLayoutManager(getApplicationContext());
        recyclerview.setLayoutManager(layoutMgr);
        recyclerview.setAdapter(adapter);

        ItemTouchHelper helper = new ItemTouchHelper(new ItemSwipeCallback(this, mColors,
                0, ItemTouchHelper.RIGHT, new ItemSwipeCallback.OnTouchListener() {

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                // Do something here
            }
        }));

        helper.attachToRecyclerView(recyclerview);
    }

    private void populateColors() {
        mColors.add(new ColorItem("Red", R.color.red));
        mColors.add(new ColorItem("White", R.color.white));
        mColors.add(new ColorItem("Green", R.color.green));
        mColors.add(new ColorItem("Yellow", R.color.yellow));
        mColors.add(new ColorItem("Black", R.color.black));
        mColors.add(new ColorItem("Red", R.color.red));
        mColors.add(new ColorItem("White", R.color.white));
        mColors.add(new ColorItem("Green", R.color.green));
        mColors.add(new ColorItem("Yellow", R.color.yellow));
        mColors.add(new ColorItem("Black", R.color.black));
        mColors.add(new ColorItem("Red", R.color.red));
        mColors.add(new ColorItem("White", R.color.white));
        mColors.add(new ColorItem("Green", R.color.green));
        mColors.add(new ColorItem("Yellow", R.color.yellow));
        mColors.add(new ColorItem("Black", R.color.black));
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM