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);
}
}
}
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
User contributions licensed under CC BY-SA 3.0