How to display icon in ItemTouchHelper?

0

I am using an ItemTouchHelper for my RecyclerView. I've assigned icons for swiping both left and right. The icon for swiping right is being displayed correctly, but the icon for swiping left is not being displayed. Here's some of my code from the top of the ItemTouchHelper.SimpleCallback class:

    private RecyclerView.Adapter adapter;
    private Drawable leftIcon;
    private Drawable rightIcon;
    private final ColorDrawable leftBackground;
    private final ColorDrawable rightBackground;
    private int BACKGROUND_CORNER_OFFSET = 20;

    SwipeCallback(RecyclerView.Adapter adapter,
                  Drawable leftIcon, Drawable rightIcon,
                  int leftBackgroundColor, int rightBackgroundColor) {
        super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);

        this.adapter = adapter;
        this.leftIcon = leftIcon;
        this.rightIcon = rightIcon;
        this.leftBackground = new ColorDrawable(leftBackgroundColor);
        this.rightBackground = new ColorDrawable(rightBackgroundColor);
    }

And here's the part where I set the icons:

        if (dX > 0) {
            int leftIconMargin = (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;

            int leftIconTop = itemView.getTop() + (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;
            int leftIconBottom = leftIconTop + leftIcon.getIntrinsicHeight();
            int leftIconLeft = itemView.getLeft() + leftIconMargin + leftIcon.getIntrinsicWidth();
            int leftIconRight = itemView.getLeft() + leftIconMargin;
            leftIcon.setBounds(leftIconLeft, leftIconTop, leftIconRight, leftIconBottom);

            leftBackground.setBounds(itemView.getLeft(), itemView.getTop(),
                               itemView.getLeft() + ((int) dX) + backgroundCornerOffset,
                                     itemView.getBottom());

            leftBackground.draw(c);
            leftIcon.draw(c);
        } else if (dX < 0) {
            int rightIconMargin = (itemView.getHeight() - rightIcon.getIntrinsicHeight()) / 2;

            int rightIconTop = itemView.getTop() + (itemView.getHeight() - rightIcon.getIntrinsicHeight()) / 2;
            int rightIconBottom = rightIconTop + rightIcon.getIntrinsicHeight();
            int rightIconLeft = itemView.getRight() - rightIconMargin -rightIcon.getIntrinsicWidth();
            int rightIconRight = itemView.getRight() - rightIconMargin;
            rightIcon.setBounds(rightIconLeft, rightIconTop, rightIconRight, rightIconBottom);

            rightBackground.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
                                              itemView.getTop(), itemView.getRight(), itemView.getBottom());

            rightBackground.draw(c);
            rightIcon.draw(c);
        } else {
            leftBackground.setBounds(0, 0, 0, 0);
            rightBackground.setBounds(0, 0, 0, 0);

            leftBackground.draw(c);
            leftIcon.draw(c);
            rightBackground.draw(c);
            rightIcon.draw(c);
        }

I've carefully looked over my code, but I don't see any difference between how I set the right icon and the left icon. Here's my code for instantiating the ItemTouchHelper:

        itemTouchHelper = new ItemTouchHelper(new SwipeCallback(adapter,
                ContextCompat.getDrawable(getApplicationContext(), R.drawable.baseline_archive_24),
                ContextCompat.getDrawable(getApplicationContext(), R.drawable.baseline_delete_24),
                0xff0099ff, 0xffff0000));

I downloaded my icons from https://material.io/resources/icons/. Here is my xml file for the right (delete) icon:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/white"
      android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
</vector>

And here is my xml file for left (archive) icon:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/white"
      android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0 -0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93 -0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
</vector>

I've tried substituting another icon for the left (archive) icon, but it didn't make a difference; there was still no icon on swiping left.

Just for reference, I'm pasting my entire ItemTouchHelper.SimpleCallback class:

package com.example.treeapp;

import android.graphics.Canvas;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

public class SwipeCallback extends ItemTouchHelper.SimpleCallback {
    private RecyclerView.Adapter adapter;
    private Drawable leftIcon;
    private Drawable rightIcon;
    private final ColorDrawable leftBackground;
    private final ColorDrawable rightBackground;
    private int BACKGROUND_CORNER_OFFSET = 20;

    SwipeCallback(RecyclerView.Adapter adapter,
                  Drawable leftIcon, Drawable rightIcon,
                  int leftBackgroundColor, int rightBackgroundColor) {
        super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);

        this.adapter = adapter;
        this.leftIcon = leftIcon;
        this.rightIcon = rightIcon;
        this.leftBackground = new ColorDrawable(leftBackgroundColor);
        this.rightBackground = new ColorDrawable(rightBackgroundColor);
    }

    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
        int position = viewHolder.getAdapterPosition();

        if (viewHolder instanceof PlanterMessagesAdapter.PlanterMessagesViewHolder) {
            PlanterMessagesAdapter planterMessagesAdapter = (PlanterMessagesAdapter) adapter;

            if (direction == ItemTouchHelper.LEFT) {
                planterMessagesAdapter.deleteMessages(position);
            } else if (direction == ItemTouchHelper.RIGHT) {
                planterMessagesAdapter.archiveMessages(position);
            }
        } else if (viewHolder instanceof DonorMessagesAdapter.DonorMessagesViewHolder) {
            DonorMessagesAdapter donorMessagesAdapter = (DonorMessagesAdapter) adapter;

            if (direction == ItemTouchHelper.LEFT) {
                donorMessagesAdapter.deleteMessages(position);
            } else if (direction == ItemTouchHelper.RIGHT) {
                donorMessagesAdapter.archiveMessages(position);
            }
        } else if (viewHolder instanceof ArchiveAdapter.ArchiveViewHolder) {
            ArchiveAdapter archiveAdapter = (ArchiveAdapter) adapter;

            if (direction == ItemTouchHelper.LEFT) {
                archiveAdapter.deleteMessages(position);
            } else if (direction == ItemTouchHelper.RIGHT) {
                archiveAdapter.unarchiveMessages(position);
            }
        }
    }

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

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

        View itemView = viewHolder.itemView;
        int backgroundCornerOffset = BACKGROUND_CORNER_OFFSET;

        // Draw background
        if (dX > 0) {
            leftBackground.setBounds(itemView.getLeft(), itemView.getTop(),
                               itemView.getLeft() + ((int) dX) + backgroundCornerOffset,
                                     itemView.getBottom());

            leftBackground.draw(c);
        } else if (dX < 0) {
            rightBackground.setBounds(itemView.getRight() + ((int) dX) + backgroundCornerOffset,
                                           itemView.getTop(), itemView.getRight(), itemView.getBottom());

            rightBackground.draw(c);
        } else {
            leftBackground.setBounds(0, 0, 0, 0);
            rightBackground.setBounds(0, 0, 0, 0);

            leftBackground.draw(c);
            rightBackground.draw(c);
        }

        // Draw icon
        if (dX > 0) {
            int leftIconMargin = (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;

            int leftIconTop = itemView.getTop() + (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;
            int leftIconBottom = leftIconTop + leftIcon.getIntrinsicHeight();
            int leftIconLeft = itemView.getLeft() + leftIconMargin + leftIcon.getIntrinsicWidth();
            int leftIconRight = itemView.getLeft() + leftIconMargin;
            leftIcon.setBounds(leftIconLeft, leftIconTop, leftIconRight, leftIconBottom);

            leftBackground.setBounds(itemView.getLeft(), itemView.getTop(),
                               itemView.getLeft() + ((int) dX) + backgroundCornerOffset,
                                     itemView.getBottom());

            leftBackground.draw(c);
            leftIcon.draw(c);
        } else if (dX < 0) {
            int rightIconMargin = (itemView.getHeight() - rightIcon.getIntrinsicHeight()) / 2;

            int rightIconTop = itemView.getTop() + (itemView.getHeight() - rightIcon.getIntrinsicHeight()) / 2;
            int rightIconBottom = rightIconTop + rightIcon.getIntrinsicHeight();
            int rightIconLeft = itemView.getRight() - rightIconMargin -rightIcon.getIntrinsicWidth();
            int rightIconRight = itemView.getRight() - rightIconMargin;
            rightIcon.setBounds(rightIconLeft, rightIconTop, rightIconRight, rightIconBottom);

            rightBackground.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
                                              itemView.getTop(), itemView.getRight(), itemView.getBottom());

            rightBackground.draw(c);
            rightIcon.draw(c);
        } else {
            leftBackground.setBounds(0, 0, 0, 0);
            rightBackground.setBounds(0, 0, 0, 0);

            leftBackground.draw(c);
            leftIcon.draw(c);
            rightBackground.draw(c);
            rightIcon.draw(c);
        }
    }
}

android
android-recyclerview
asked on Stack Overflow Sep 10, 2020 by Huzaifa

1 Answer

0

Sorry, I made the following mistake in when displaying the left icon (The mistake is commented and the two lines below it are the correct code):

        if (dX > 0) {
            int leftIconMargin = (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;

            int leftIconTop = itemView.getTop() + (itemView.getHeight() - leftIcon.getIntrinsicHeight()) / 2;
            int leftIconBottom = leftIconTop + leftIcon.getIntrinsicHeight();
//            int leftIconLeft = itemView.getLeft() + leftIconMargin + leftIcon.getIntrinsicWidth();
//            int leftIconRight = itemView.getLeft() + leftIconMargin;
            int leftIconLeft = itemView.getLeft() + leftIconMargin;
            int leftIconRight = itemView.getLeft() + leftIconMargin + leftIcon.getIntrinsicWidth();
            leftIcon.setBounds(leftIconLeft, leftIconTop, leftIconRight, leftIconBottom);

            leftBackground.setBounds(itemView.getLeft(), itemView.getTop(),
                               itemView.getLeft() + ((int) dX) + backgroundCornerOffset,
                                     itemView.getBottom());

            leftBackground.draw(c);
            leftIcon.draw(c);
        }

I was following this tutorial: Step by Step: RecyclerView Swipe to Delete and Undo. So if anyone else is also following this tutorial, make sure to change these lines

answered on Stack Overflow Sep 12, 2020 by Huzaifa

User contributions licensed under CC BY-SA 3.0