我的RecyclerView支持使用ItemTouchHelper滑动正确的功能,如下所示
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(createHelperCallback());
itemTouchHelper.attachToRecyclerView(myRecyclerView);
private ItemTouchHelper.Callback createHelperCallback() {
return new ItemDragSwipeCallback(this, R.color.swipe_delete, R.drawable.ic_delete_black_24dp,
0, ItemTouchHelper.RIGHT, new ItemDragSwipeCallback.OnTouchListener() {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
// delete code
}
});
}
自定义ItemTouchHelper.SimpleCallback
public class ItemDragSwipeCallback extends ItemTouchHelper.SimpleCallback {
private Drawable mIcon;
private final ColorDrawable mBackground;
public interface OnTouchListener {
boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target);
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);
}
private OnTouchListener mOnTouchListener;
public ItemDragSwipeCallback(Context context, int backgroundColor, int drawable, int dragDirs, int swipeDirs, OnTouchListener onTouchListener) {
super(dragDirs, swipeDirs);
mOnTouchListener = onTouchListener;
mIcon = ContextCompat.getDrawable(context, drawable);
mBackground = new ColorDrawable(context.getResources().getColor(backgroundColor));
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return mOnTouchListener.onMove(recyclerView, viewHolder, target);
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mOnTouchListener.onSwiped(viewHolder, direction);
}
@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 = 25; //so mBackground is behind the rounded corners of itemView
int iconMargin = (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconTop = itemView.getTop() + (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconBottom = iconTop + mIcon.getIntrinsicHeight();
if (dX > 0) { // Swiping to the right
int iconLeft = itemView.getLeft() + iconMargin;
int iconRight = iconLeft + mIcon.getIntrinsicWidth();
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + ((int) dX) + backgroundCornerOffset, itemView.getBottom());
} else if (dX < 0) { // Swiping to the left
int iconLeft = itemView.getRight() - iconMargin - mIcon.getIntrinsicWidth();
int iconRight = itemView.getRight() - iconMargin;
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
itemView.getTop(), itemView.getRight(), itemView.getBottom());
} else { // view is unSwiped
mBackground.setBounds(0, 0, 0, 0);
}
mBackground.draw(c);
mIcon.draw(c);
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
我的问题是,当我假装滑动删除某个项目并改回主意时,直到我触摸屏幕进行任何其他操作时,可绘制删除图标才会隐藏。
更新:我通过将list_item的背景颜色更改为某种颜色找到了补救措施。但如果我需要透明背景,这不是正确的解决方案。
修改了自定义ItemTouchHelper.SimpleCallback的onChildDraw(),通过使用mIcon.setBounds(0, 0, 0, 0);
取消擦除时将图标的边界设置为0
public class ItemDragSwipeCallback extends ItemTouchHelper.SimpleCallback {
private Drawable mIcon;
private final ColorDrawable mBackground;
public interface OnTouchListener {
boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target);
void onSwiped(RecyclerView.ViewHolder viewHolder, int direction);
}
private OnTouchListener mOnTouchListener;
public ItemDragSwipeCallback(Context context, int backgroundColor, int drawable, int dragDirs, int swipeDirs, OnTouchListener onTouchListener) {
super(dragDirs, swipeDirs);
mOnTouchListener = onTouchListener;
mIcon = ContextCompat.getDrawable(context, drawable);
mBackground = new ColorDrawable(context.getResources().getColor(backgroundColor));
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return mOnTouchListener.onMove(recyclerView, viewHolder, target);
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
mOnTouchListener.onSwiped(viewHolder, direction);
}
@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 = 25; //so mBackground is behind the rounded corners of itemView
int iconMargin = (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconTop = itemView.getTop() + (itemView.getHeight() - mIcon.getIntrinsicHeight()) / 2;
int iconBottom = iconTop + mIcon.getIntrinsicHeight();
if (dX > 0) { // Swiping to the right
int iconLeft = itemView.getLeft() + iconMargin;
int iconRight = iconLeft + mIcon.getIntrinsicWidth();
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getLeft(), itemView.getTop(),
itemView.getLeft() + ((int) dX) + backgroundCornerOffset, itemView.getBottom());
} else if (dX < 0) { // Swiping to the left
int iconLeft = itemView.getRight() - iconMargin - mIcon.getIntrinsicWidth();
int iconRight = itemView.getRight() - iconMargin;
mIcon.setBounds(iconLeft, iconTop, iconRight, iconBottom);
mBackground.setBounds(itemView.getRight() + ((int) dX) - backgroundCornerOffset,
itemView.getTop(), itemView.getRight(), itemView.getBottom());
} else { // view is unSwiped
mIcon.setBounds(0, 0, 0, 0);
mBackground.setBounds(0, 0, 0, 0);
}
mBackground.draw(c);
mIcon.draw(c);
}
}