使用TouchHelperCallback对Recyclerview进行部分和完全滑动

时间:2016-01-12 15:23:44

标签: android android-recyclerview

我正在尝试使用api TouchHelperCallback实现Recyclerview的部分和完全滑动,遇到像https://github.com/daimajia/AndroidSwipeLayouthttps://github.com/hudomju/android-swipe-to-dismiss-undo之类的库,但是如何使用api实现这一目标?

我能够使用以下代码完全滑动,任何人都可以就如何解决此问题提出建议。

由于

代码库:

ExtendItemTouchHelperCallback:

import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;


public abstract class ExtendItemTouchHelperCallback extends ItemTouchHelper.Callback
{

    private int mCachedMaxScrollSpeed = -1; // default
    private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000; // default

    @Override
    public abstract int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder);

    @Override
    public abstract boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder viewHolder1);

    @Override
    public abstract void onSwiped(RecyclerView.ViewHolder viewHolder, int i);


    @Override
    public abstract void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder);

    @Override
    public abstract void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState);

    @Override
    public abstract void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);

    @Override
    public abstract void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive);


    // default
    @Override
    public int interpolateOutOfBoundsScroll(RecyclerView recyclerView, int viewSize, int viewSizeOutOfBounds, int totalSize, long msSinceStartScroll)
    {
//        return super.interpolateOutOfBoundsScroll(recyclerView, viewSize, viewSizeOutOfBounds, totalSize, msSinceStartScroll);
        final int maxScroll = Util.getMaxDragScroll(recyclerView);
        final int absOutOfBounds = Math.abs(viewSizeOutOfBounds);
        final int direction = (int) Math.signum(viewSizeOutOfBounds);
        // might be negative if other direction
        float outOfBoundsRatio = Math.min(1f, 1f * absOutOfBounds / viewSize);
        final int cappedScroll = (int) (direction * maxScroll *
                Util.sDragViewScrollCapInterpolator.getInterpolation(outOfBoundsRatio));
        final float timeRatio;
        if (msSinceStartScroll > DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS)
        {
            timeRatio = 1f;
//            timeRatio = 3f;
        }
        else
        {
            timeRatio = (float) msSinceStartScroll / DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS;
        }
        final int value = (int) (cappedScroll * Util.sDragScrollInterpolator.getInterpolation(timeRatio));
        if (value == 0)
        {
            return viewSizeOutOfBounds > 0 ? 1 : -1;
        }
        return value;
    }


}

的Util:

import android.support.v7.widget.RecyclerView;
import android.view.animation.Interpolator;

public class Util
{
    private static int mCachedMaxScrollSpeed = -1; // default
    private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000; // default

    // default
    public static int getMaxDragScroll(RecyclerView recyclerView)
    {
        if (mCachedMaxScrollSpeed == -1)
        {
            mCachedMaxScrollSpeed = recyclerView.getResources().getDimensionPixelSize(android.support.v7.recyclerview.R.dimen.item_touch_helper_max_drag_scroll_per_frame);
        }
        return mCachedMaxScrollSpeed;
    }

    // default
    public static final Interpolator sDragScrollInterpolator = new Interpolator()
    {
        public float getInterpolation(float t)
        {
//            return t * t * t * t * t; // default return value, but it's too late for me
            return (int) Math.pow(2, (double) t); // optional whatever you like        }
        }

    };

    // default
    public static final Interpolator sDragViewScrollCapInterpolator = new Interpolator()
    {
        public float getInterpolation(float t)
        {
            t -= 1.0f;
            return t * t * t * t * t + 10.0f;
        }
    };

}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="80dp"
    >


    <LinearLayout
        android:id="@+id/list_item_facade_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:minHeight="?android:attr/listPreferredItemHeight"
        android:orientation="vertical"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingTop="8dp">


        <TextView
            android:id="@+id/list_item_main_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Main text"
            android:textColor="@android:color/black"/>


        <TextView
            android:id="@+id/list_item_sub_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="sub text"
            android:textColor="@android:color/black"/>


    </LinearLayout>

    <RelativeLayout
        android:id="@+id/list_item_rear_right_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_red_dark"
        android:visibility="invisible">

        <Button
            android:id="@android:id/button1"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="16dp"
            android:background="@drawable/ic_launcher"
            android:gravity="center"/>

    </RelativeLayout>


    <RelativeLayout
        android:id="@+id/list_item_rear_left_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/holo_green_dark"
        android:visibility="invisible">

        <Button
            android:id="@android:id/button1"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="16dp"
            android:background="@drawable/ic_action_remove"
            android:gravity="center"/>

    </RelativeLayout>

</RelativeLayout>

并在活动中实施回调

private ItemTouchHelper.Callback crateCallback()
    {
        return new ExtendItemTouchHelperCallback()
        {
            @Override
            public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
            {

                if (viewHolder instanceof ItemAdapter.ViewHolder)
                {

                    //this make sure that the value works for the drag and drop too
                    //return makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT) | makeFlag(ItemTouchHelper.ACTION_STATE_DRAG, ItemTouchHelper.UP | ItemTouchHelper.DOWN);
                    return makeFlag(ItemTouchHelper.ACTION_STATE_SWIPE, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT);

                }
                return 0;
            }

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)
            {
                final int fromPos = viewHolder.getAdapterPosition();
                final int toPos = target.getAdapterPosition();
                Log.d(LOG_TAG, " postion " + "From: " + fromPos + " TO: " + toPos);
                mItemAdapter.move(fromPos, toPos);
                return true;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int i)
            {
                int removedId = mItemAdapter.remove(viewHolder.getAdapterPosition());

               // Snackbar.make(mRecyclerView, "Item removed, position: " + removedId, Snackbar.LENGTH_SHORT).show();


                //ExtendAsyncQueryHandler extendAsyncQueryHandler = new ExtendAsyncQueryHandler(getActivity().getContentResolver());
                //extendAsyncQueryHandler.startDelete(removedId, null, DataContract.ItemEntry.buildItemUri(removedId), null, null);

                Log.d(LOG_TAG, "removed row; " + removedId);
            }

            @Override
            public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder)
            {
                getDefaultUIUtil().clearView(((ItemAdapter.ViewHolder) viewHolder).mFacadeLayout);
//                getDefaultUIUtil().clearView(((ItemAdapter.ViewHolder) viewHolder).itemView);//                ((ItemAdapter.ViewHolder) viewHolder).setLayoutVisibility(false);
                ((ItemAdapter.ViewHolder) viewHolder).setLayoutVisibility(ItemAdapter.SWIPE_END);
            }

            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState)
            {
                if (viewHolder != null) {
                    if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
                        getDefaultUIUtil().onSelected(((ItemAdapter.ViewHolder) viewHolder).mFacadeLayout);
//                        ((ItemAdapter.ViewHolder) viewHolder).setLayoutVisibility(true);
                    } else if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {

                        getDefaultUIUtil().onSelected(((ItemAdapter.ViewHolder) viewHolder).itemView);
                    } else {
                        getDefaultUIUtil().onSelected(((ItemAdapter.ViewHolder) viewHolder).itemView);
                    }


                }
            }

            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
            {
                Log.d(LOG_TAG, "dx: " + dX + " dy: " + dY);



                if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {

                    float swipingDx = dX;
                    String swipingDirection;
                    if (swipingDx > 0) {
                        swipingDirection = ItemAdapter.SWIPING_RIGHT;
                    } else if (swipingDx < 0) {
                        swipingDirection = ItemAdapter.SWIPING_LEFT;
                    } else {
                        swipingDirection = ItemAdapter.SWIPE_END;
                    }
//                    String swipingDirection = swipingDx > 0 ? ItemAdapter.SWIPING_RIGHT :ItemAdapter.SWIPING_LEFT;

                    getDefaultUIUtil().onDraw(c, recyclerView,
                            ((ItemAdapter.ViewHolder) viewHolder).mFacadeLayout, dX, dY,
                            actionState, isCurrentlyActive);
                    ((ItemAdapter.ViewHolder) viewHolder).setLayoutVisibility(swipingDirection);

                } else {
                    getDefaultUIUtil().onDraw(c, recyclerView,
                            ((ItemAdapter.ViewHolder) viewHolder).itemView, dX, dY,
                            actionState, isCurrentlyActive);

                }
            }

            @Override
            public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive)
            {
                if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
                    getDefaultUIUtil().onDrawOver(c, recyclerView,
                            ((ItemAdapter.ViewHolder) viewHolder).mFacadeLayout, dX, dY,
                            actionState, isCurrentlyActive);
                } else {
                    getDefaultUIUtil().onDraw(c, recyclerView,
                            ((ItemAdapter.ViewHolder) viewHolder).itemView, dX, dY,
                            actionState, isCurrentlyActive);
//                    ((ItemAdapter.ViewHolder) viewHolder).setLayoutVisibility(false);                }
                }


            }
        };

    }

0 个答案:

没有答案