RecyclerView с разными ItemTouchHelper для каждого элемента в списке

Я пытаюсь реализовать Recycleview с разными ItemTouchHelper для каждого элемента в списке.

Единственный известный мне способ — добавить ItemTouchHelper непосредственно в RecycleView, а не в элемент.

Пример того, что я пытаюсь сделать:

У меня есть список из 4 элементов, и все элементы я могу провести влево.

  • Первый элемент покажет кнопку удаления.

  • Второй элемент будет отображать кнопку удаления и кнопку редактирования.

  • Третий элемент показывает кнопку удаления.

  • Четвертый элемент показывает кнопку копирования, удаления и редактирования.

*В списке может быть много пунктов.

Кто-нибудь знает, как это сделать?


person groff07    schedule 14.08.2020    source источник


Ответы (1)


Идея

Итак, в основном ваш вопрос касается того, как добавить уникальный ItemTouchHelper к каждому элементу RecyclerView на основе типа элемента.

Не вдаваясь в детали того, как вы хотите, чтобы каждый элемент отличался в ItemTouchHelper действии смахивания, как вы сказали, добавить некоторые функции кнопок, такие как копирование, редактирование и удаление. Я буду прямо в точку, как различать свайпы ItemTouchHelper для разных предметов.

Шаги

Шаг 1. Различение RecyclerView элементов с помощью поля POJO

Итак, сначала вам нужно создать поле в вашем POJO (обычно int или enum), которое различает разные элементы.

Шаг 2. Создайте собственный ItemTouchHelper.SimpleCallback

Создайте собственный класс ItemTouchHelper.SimpleCallback, который принимает список элементов RecyclerView в свой конструктор.

Затем переопределите onChildDraw(), который вызывается ItemTouchHelper при обратном вызове RecyclerView onDraw(); и это правильное место, поскольку оно вызывается всякий раз, когда RecyclerView рисует свои отдельные элементы.

Итак, в этом методе вы можете реализовать то, как вы хотите, чтобы каждый элемент выглядел при смахивании. И так как он принимает экземпляр ViewHolder, вы можете получить позицию сдвинутого элемента с помощью ViewHolder.getAdapterPosition(), а из предоставленного списка элементов вы можете получить сдвинутый элемент этой конкретной позиции.

Пример

Вот простой пример, представляющий собой список цветов, который отражает цвет фона всякий раз, когда вы проводите пальцем по определенному элементу.

Вот как это выглядит:

ПОЖО

Для вышеупомянутого шага 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 (без причудливого кода)

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);
        }

      
    }
}

Пользовательский 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);

    }
}

Мероприятия

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));
    }

}
person Zain    schedule 14.08.2020
comment
Понравилось ваше объяснение. Это помогло мне реализовать мое решение. Спасибо :) - person groff07; 14.08.2020