我正在尝试为recyclerview添加自定义滑动视图。以下代码运行良好。从this link获得。在此代码中,按钮是通过onDraw方法创建的。
enum ButtonsState {
GONE,LEFT_VISIBLE,RIGHT_VISIBLE
}
class SwipeController extends Callback {
private boolean swipeBack = false;
private ButtonsState buttonShowedState = ButtonsState.GONE;
private RectF buttonInstance = null;
private RecyclerView.ViewHolder currentitemViewHolder = null;
private SwipeControlleractions buttonsactions = null;
private static final float buttonWidth = 300;
public SwipeController(SwipeControlleractions buttonsactions) {
this.buttonsactions = buttonsactions;
}
@Override
public int getMovementflags(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) {
return makeMovementflags(0,LEFT | RIGHT);
}
@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,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,isCurrentlyactive);
}
}
if (buttonShowedState == ButtonsState.GONE) {
super.onChildDraw(c,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,isCurrentlyactive);
setItemsClickable(recyclerView,false);
}
}
return false;
}
});
}
private void setTouchDownListener(final Canvas c,MotionEvent event) {
if (event.getaction() == MotionEvent.actION_DOWN) {
setTouchUpListener(c,isCurrentlyactive);
}
return false;
}
});
}
private void setTouchUpListener(final Canvas c,MotionEvent event) {
if (event.getaction() == MotionEvent.actION_UP) {
SwipeController.super.onChildDraw(c,0F,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) {
float buttonWidthWithoutPadding = buttonWidth - 20;
float corners = 16;
View itemView = viewHolder.itemView;
Paint p = new Paint();
RectF leftButton = new RectF(itemView.getLeft(),itemView.getTop(),itemView.getLeft() + buttonWidthWithoutPadding,itemView.getBottom());
p.setColor(Color.BLUE);
c.drawRoundRect(leftButton,corners,p);
drawText("EDIT",c,leftButton,p);
RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding,itemView.getRight(),itemView.getBottom());
p.setColor(Color.RED);
c.drawRoundRect(rightButton,p);
drawText("DELETE",rightButton,p);
buttonInstance = null;
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
buttonInstance = leftButton;
}
else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
buttonInstance = rightButton;
}
}
private void drawText(String text,Canvas c,RectF button,Paint p) {
float textSize = 60;
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 onDrawing(Canvas c) {
if (currentitemViewHolder != null) {
drawButtons(c,currentitemViewHolder);
}
}
}
但是我想将视图附加到滑动上。所以我修改了如下代码。我可以向右滑动此代码。但是,如果我再次单击或滑动,则滑动的项目不会关闭。还有一些时间视图从recyclerview中退出。请帮助我。
public class SwipeTouchListener extends ItemTouchHelper.Callback {
private boolean swipeBack = false;
private boolean allowSwipeleft,allowSwipeRight;
private List<Integer> unSwipablePosition = new ArrayList<>();
private ButtonsState buttonShowedState = ButtonsState.GONE;
private static final float buttonWidth = 300;
private SwipeControlleractions buttonsactions = null;
private RectF buttonInstance = null;
private View foregroundView = null;
public void setSwipeDirection(boolean allowSwipeleft,boolean allowSwipeRight){
this.allowSwipeleft = allowSwipeleft;
this.allowSwipeRight = allowSwipeRight;
}
public void setUnSwipeableRows(Integer... rows) {
this.unSwipablePosition = new ArrayList<>(Arrays.asList(rows));
}
private int getSwipeflags(){
if(allowSwipeRight && allowSwipeleft)
return LEFT|RIGHT;
else if(allowSwipeleft)
return LEFT;
else if(allowSwipeRight)
return RIGHT;
return 0;
}
@Override
public int getMovementflags(@NonNull RecyclerView recyclerView,@NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementflags(0,getSwipeflags());
}
@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 direction) {
}
@Override
public int convertToAbsoluteDirection(int flags,int layoutDirection) {
if (swipeBack) {
swipeBack = false;
return 0;
}
return super.convertToAbsoluteDirection(flags,boolean isCurrentlyactive) {
int currentPosition = ((RecyclerAdapter.MyViewHolder) viewHolder).getadapterPosition();
if(unSwipablePosition.contains(currentPosition))
return;
foregroundView = ((RecyclerAdapter.MyViewHolder) viewHolder).viewForeground;
if (actionState == actION_STATE_SWIPE) {
if (buttonShowedState != ButtonsState.GONE) {
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX,-buttonWidth);
//Adding foreground layout
getDefaultUIUtil().onDraw(c,foregroundView,isCurrentlyactive);
} else {
setTouchListener(c,isCurrentlyactive);
}
}
if (buttonShowedState == ButtonsState.GONE) {
//Adding foreground layout
getDefaultUIUtil().onDraw(c,isCurrentlyactive);
}
}
private void setTouchListener(final Canvas c,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,MotionEvent event) {
if (event.getaction() == MotionEvent.actION_DOWN) {
setTouchUpListener(c,MotionEvent event) {
if (event.getaction() == MotionEvent.actION_UP) {
//Adding foreground layout
getDefaultUIUtil().onDraw(c,false);
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v,MotionEvent event) {
return 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());
}
}
setItemsClickable(recyclerView,true);
swipeBack = false;
buttonShowedState = ButtonsState.GONE;
}
return false;
}
});
}