I am trying to have a custom view (or image) appear when swiping left/right.
I'm close to having it working, however I'm having issues with using a custom image.
The effect I'm going for is similar to this: RecyclerView ItemTouchHelper swipe remove animation
See what's happening below. It's warping the image as the swipe happens:
Below is what my code looks like:
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder,
float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
View itemView = viewHolder.itemView;
Paint p = new Paint();
if (dX > 0) {
Drawable d = ContextCompat.getDrawable(getActivity(), R.drawable.test_check);
d.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
d.draw(c);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
How can I keep the image static while continuing to draw the background color? Is it possible to even use an Android view instead of an image? Similar to this: https://github.com/wdullaer/SwipeActionAdapter
Creates an ItemTouchHelper that will work with the given Callback. You can attach ItemTouchHelper to a RecyclerView via attachToRecyclerView (RecyclerView). Upon attaching, it will add an item decoration, an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
Apart from listed data, RecyclerView has some crucial decorative elements, such as scroll bars and dividers between items. And that’s where RecyclerView.ItemDecoration can help us draw all of the elements without having to spawn any unnecessary Views while we render items and screens.
There are two methods you can use to add an ItemDecoration instance to RecyclerView: All added instances of RecyclerView.ItemDecoration are put in a single list and drawn simultaneously.
I’ll show you what it’s capable of and how to implement it when rendering a list. Apart from listed data, RecyclerView has some crucial decorative elements, such as scroll bars and dividers between items.
You can prepare your recycler view item layout to include the check symbol ImageView
and maybe another blank view with just the background color. You should also move all the swipeable content into a nested layout. Assign a reference to the swipeable content in your view holder. Then just call setTranslationX
on your swipeable content in onChildDraw
, like:
((MyViewHolder) viewHolder).swipeableContent.setTranslationX(dX);
Recycler view item layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/recycler_view_item_height"
android:background="@color/transparent">
<!-- background color view -->
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/purple" />
<!-- check symbol image view -->
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/check_symbol_width"
android:contentDescription="@null"
android:src="@drawable/check_symbol" />
<!-- swipeable content container -->
<LinearLayout
android:id="@+id/swipeable_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- here goes your swipeable content -->
</LinearLayout>
</RelativeLayout>
View holder class:
class MyViewHolder extends RecyclerView.ViewHolder {
// Swipeable content container.
LinearLayout swipeableContent;
/*
... here goes other sub-views
*/
public ExpenseViewHolder(final View itemView) {
super(itemView);
// bind swipeable content container view
swipeableContent = (LinearLayout) itemView.findViewById(R.id.swipeable_content);
/*
... bind other sub-views
*/
}
}
ItemTouchHelper.Callback subclass:
class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
@Override
public void onChildDraw(final Canvas c,
final RecyclerView recyclerView,
final RecyclerView.ViewHolder viewHolder,
final float dX,
final float dY,
final int actionState,
final boolean isCurrentlyActive) {
if (viewHolder instanceof MyViewHolder) {
// translate by swipe amount,
// the check symbol and the background will stay in place
((MyViewHolder) viewHolder).swipeableContent.setTranslationX(dX);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With