我正在尝试使用api TouchHelperCallback实现Recyclerview的部分和完全滑动,遇到像https://github.com/daimajia/AndroidSwipeLayout和https://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); }
}
}
};
}