@Павел Карпычев 解决方案实际上几乎是正确的
notifyItemChanged 的问题在于它执行了额外的动画,并且可能与来自onDraw 的装饰重叠,所以只做一个干净的幻灯片,这就是你可以做的:
public class SimpleSwipeCallback extends ItemTouchHelper.SimpleCallback {
boolean swipeOutEnabled = true;
int swipeDir = 0;
public SimpleSwipeCallback() {
super(0, ItemTouchHelper.RIGHT | ItemTouchHelper.LEFT);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int swipeDir) {
//Do action
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder,
float dx, float dy, int actionState, boolean isCurrentlyActive) {
//check if it should swipe out
boolean shouldSwipeOut = //TODO;
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE && (!shouldSwipeOut) {
swipeOutEnabled = false;
//Limit swipe
int maxMovement = recyclerView.getWidth() / 3;
//swipe right : left
float sign = dx > 0 ? 1 : -1;
float limitMovement = Math.min(maxMovement, sign * dx); // Only move to maxMovement
float displacementPercentage = limitMovement / maxMovement;
//limited threshold
boolean swipeThreshold = displacementPercentage == 1;
// Move slower when getting near the middle
dx = sign * maxMovement * (float) Math.sin((Math.PI / 2) * displacementPercentage);
if (isCurrentlyActive) {
int dir = dx > 0 ? ItemTouchHelper.RIGHT : ItemTouchHelper.LEFT;
swipeDir = swipeThreshold ? dir : 0;
}
} else {
swipeOutEnabled = true;
}
//do decoration
super.onChildDraw(c, recyclerView, viewHolder, dx, dy, actionState, isCurrentlyActive);
}
@Override
public float getSwipeEscapeVelocity(float defaultValue) {
return swipeOutEnabled ? defaultValue : Float.MAX_VALUE;
}
@Override
public float getSwipeVelocityThreshold(float defaultValue) {
return swipeOutEnabled ? defaultValue : 0;
}
@Override
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
return swipeOutEnabled ? 0.6f : 1.0f;
}
@Override
public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder);
if (swipeDir != 0) {
onSwiped(viewHolder, swipeDir);
swipeDir = 0;
}
}
}
请注意,这会启用正常滑动(“swipeOut”)或有限滑动,具体取决于shouldSwipeOut