具有自定义滑动视图的Android Recycler

我正在尝试为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;
            }
        });
    }

Output Gif

yhgfhgfhgfgfhgfh 回答:具有自定义滑动视图的Android Recycler

似乎您正在尝试重新发明轮子:) 请看看那个AndroidSwipeLayou并适应自己。我在大多数项目中都使用了它,效果很好。

本文链接:https://www.f2er.com/1368872.html

大家都在问