简体   繁体   中英

RecyclerView ItemTouchHelper - Custom View

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

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

Update With Source Code Example:

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

}

I am not sure whether you got solution or not and also not sure whether you have seen this library or not.

I have try Android-SwipeListView library for one of my project and SwipeMenuListView for another project for something similar requirements.

Both are working fine in their place. You should give a try on that and check how it should work for your requirement.

Let me know if you need more help from me.

Enjoy Coding... :)

Simply change the (int)dX in d.setBounds() to any integer you want.

eg:

d.setBounds(itemView.getLeft(), itemView.getTop(), 50, itemView.getBottom());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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