我正在使用 RecyclerView 滑动以在列表项后面显示一个操作按钮,而我的 RecyclerView 位于带有底部导航的片段中,一切进展顺利,但有时滑动停止并卡住,因此我无法完全滑动该项目。我需要你的帮助。我的代码:
主要活动中的代码:
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeController);
itemTouchhelper.attachToRecyclerView(movelistview);
movelistview.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
swipeController.onDraw(c,"action");
}
});
Swipe Controller 类中的代码:
public class SwipeController extends ItemTouchHelper.Callback {
private static final float buttonWidth = 200;
private boolean swipeBack = false;
private ButtonsState buttonShowedState = ButtonsState.GONE;
private RectF buttonInstance = null;
private RecyclerView.ViewHolder currentItemViewHolder = null;
private SwipeControllerActions buttonsActions = null;
public SwipeController(SwipeControllerActions buttonsActions) {
this.buttonsActions = buttonsActions;
}
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(0, LEFT);
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
@Override
public int convertToAbsoluteDirection(int flags, int layoutDirection) {
if (swipeBack) {
swipeBack = buttonShowedState != ButtonsState.GONE;
return 0;
}
return super.convertToAbsoluteDirection(flags, layoutDirection);
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
if (actionState == ACTION_STATE_SWIPE) {
if (buttonShowedState != ButtonsState.GONE) {
// if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX, buttonWidth);
if (buttonShowedState == ButtonsState.RIGHT_VISIBLE)
dX = Math.min(dX, -buttonWidth);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
} else {
setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
}
if (buttonShowedState == ButtonsState.GONE) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
currentItemViewHolder = viewHolder;
}
private void setTouchListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
swipeBack = event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP;
if (swipeBack) {
if (dX < -buttonWidth) buttonShowedState = ButtonsState.RIGHT_VISIBLE;
//else if (dX > buttonWidth) buttonShowedState = ButtonsState.LEFT_VISIBLE;
if (buttonShowedState != ButtonsState.GONE) {
setTouchDownListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
setItemsClickable(recyclerView, false);
}
}
return false;
}
});
}
private void setTouchDownListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
setTouchUpListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
return false;
}
});
}
private void setTouchUpListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
SwipeController.super.onChildDraw(c, recyclerView, viewHolder, 0F, dY, actionState, isCurrentlyActive);
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
setItemsClickable(recyclerView, true);
swipeBack = false;
if (buttonsActions != null && buttonInstance != null && buttonInstance.contains(event.getX(), event.getY())) {
/*if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
buttonsActions.onLeftClicked(viewHolder.getAdapterPosition());
}else*/
if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
buttonsActions.onRightClicked(viewHolder.getAdapterPosition());
}
}
buttonShowedState = ButtonsState.GONE;
currentItemViewHolder = null;
}
return false;
}
});
}
private void setItemsClickable(RecyclerView recyclerView, boolean isClickable) {
for (int i = 0; i < recyclerView.getChildCount(); ++i) {
recyclerView.getChildAt(i).setClickable(isClickable);
}
}
private void drawButtons(Canvas c, RecyclerView.ViewHolder viewHolder, String text) {
float buttonWidthWithoutPadding = buttonWidth - 0;
float corners = 0;
View itemView = viewHolder.itemView;
Paint p = new Paint();
int position = viewHolder.getAdapterPosition();
String button_text = "Report";
if (position >= 0) {
if (MainApplication.moves_list.get(position).getMove_userId().equals(MainApplication.user_id)) {
button_text = "Delete";
} else {
button_text = "Report";
}
}
RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop() + 0, itemView.getRight(), itemView.getBottom() - 0);
p.setColor(Color.RED);
c.drawRoundRect(rightButton, corners, corners, p);
drawText(button_text, c, rightButton, p);
buttonInstance = null;
if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
buttonInstance = rightButton;
}
}
private void drawText(String text, Canvas c, RectF button, Paint p) {
float textSize = 40;
p.setColor(Color.WHITE);
p.setAntiAlias(true);
p.setTextSize(textSize);
float textWidth = p.measureText(text);
c.drawText(text, button.centerX() - (textWidth / 2), button.centerY() + (textSize / 2), p);
}
public void onDraw(Canvas c, String text) {
if (currentItemViewHolder != null) {
drawButtons(c, currentItemViewHolder, text);
}
}
}