Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有自定义滑动视图的Android回收器_Android_Android Recyclerview_Swipe Gesture - Fatal编程技术网

具有自定义滑动视图的Android回收器

具有自定义滑动视图的Android回收器,android,android-recyclerview,swipe-gesture,Android,Android Recyclerview,Swipe Gesture,我正在尝试为recyclerview添加自定义滑动视图。下面的代码工作正常。从…得到。在此代码中,按钮是在onDraw方法中创建的 enum ButtonsState { GONE, LEFT_VISIBLE, RIGHT_VISIBLE } class SwipeController extends Callback { private boolean swipeBack = false; private ButtonsState buttonSh

我正在尝试为recyclerview添加自定义滑动视图。下面的代码工作正常。从…得到。在此代码中,按钮是在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, 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) {
        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, corners, p);
        drawText("EDIT", c, leftButton, p);

        RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop(), itemView.getRight(), itemView.getBottom());
        p.setColor(Color.RED);
        c.drawRoundRect(rightButton, corners, corners, p);
        drawText("DELETE", c, 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);
        }
    }
}
enum按钮状态{
跑了,
左图可见,
右图可见
}
类SwipeController扩展回调{
私有布尔swipeBack=false;
私有ButtonState ButtonShowdState=ButtonState.GONE;
private RectF buttonInstance=null;
private RecyclerView.ViewHolder currentItemViewHolder=null;
专用SwipeControllerActions按钮操作=null;
专用静态最终浮动按钮宽度=300;
公共SwipeController(SwipeController操作按钮操作){
this.buttonActions=buttonActions;
}
@凌驾
public int getMovementFlags(RecyclerView RecyclerView,RecyclerView.ViewHolder ViewHolder){
返回makeMovementFlags(0,左|右);
}
@凌驾
公共布尔onMove(RecyclerView RecyclerView、RecyclerView.ViewHolder ViewHolder、RecyclerView.ViewHolder目标){
返回false;
}
@凌驾
公共空间(RecyclerView.ViewHolder ViewHolder,int方向){
}
@凌驾
公共int转换为绝对方向(int标志、int布局方向){
如果(回扫){
swipeBack=buttonshowdstate!=buttonstate.GONE;
返回0;
}
返回super.convertToAbsoluteDirection(标志、布局方向);
}
@凌驾
public void onChildraw(画布c、RecyclerView RecyclerView、RecyclerView.ViewHolder ViewHolder、float dX、float dY、int actionState、boolean isCurrentlyActive){
如果(actionState==操作\状态\滑动){
if(buttonshowdstate!=buttonstate.GONE){
如果(buttonshowdstate==buttonstate.LEFT_可见)dX=Math.max(dX,buttonWidth);
如果(buttonshowdstate==buttonstate.RIGHT_VISIBLE)dX=Math.min(dX,-buttonWidth);
super.onchildraw(c、recyclerView、viewHolder、dX、dY、actionState、isCurrentlyActive);
}
否则{
setTouchListener(c、recyclerView、viewHolder、dX、dY、actionState、isCurrentlyActive);
}
}
if(buttonshowdstate==buttonstate.GONE){
super.onchildraw(c、recyclerView、viewHolder、dX、dY、actionState、isCurrentlyActive);
}
currentItemViewHolder=viewHolder;
}
私有void setTouchListener(最终画布c、最终RecyclerView、最终RecyclerView.ViewHolder ViewHolder、最终浮点dX、最终浮点dY、最终整型actionState、最终布尔值isCurrentlyActive){
recyclerView.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
swipeBack=event.getAction()==MotionEvent.ACTION_CANCEL | | event.getAction()==MotionEvent.ACTION_UP;
如果(回扫){
如果(dX<-buttonWidth)buttonshowdstate=buttonstate.RIGHT_可见;
否则,如果(dX>buttonWidth)ButtonShowdState=ButtonState.LEFT_可见;
if(buttonshowdstate!=buttonstate.GONE){
setTouchDownListener(c、recyclerView、viewHolder、dX、dY、actionState、isCurrentlyActive);
setItemsClickable(recyclerView,false);
}
}
返回false;
}
});
}
私有void setTouchDownListener(最终画布c、最终RecyclerView、最终RecyclerView.ViewHolder ViewHolder、最终浮点dX、最终浮点dY、最终整型actionState、最终布尔值isCurrentlyActive){
recyclerView.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
if(event.getAction()==MotionEvent.ACTION\u向下){
setTouchUpListener(c、recyclerView、viewHolder、dX、dY、actionState、isCurrentlyActive);
}
返回false;
}
});
}
私有void setTouchUpListener(最终画布c、最终RecyclerView、最终RecyclerView.ViewHolder ViewHolder、最终浮点dX、最终浮点dY、最终整型actionState、最终布尔值为当前活动){
recyclerView.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
if(event.getAction()==MotionEvent.ACTION\u UP){
SwipeController.super.onchildraw(c、recyclerView、viewHolder、0F、dY、actionState、isCurrentlyActive);
recyclerView.setOnTouchListener(新视图.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
返回false;
}
});
setItemsClickable(recyclerView,true);
swipeBack=false;
if(buttonActions!=null&&buttonInstance!=null&&buttonInstance.contains(event.getX(),event.getY()){
if(buttonshowdstate==buttonstate.LEFT_可见){
buttonsActions.onLeftClicked(viewHolder.getAdapterPosition());
}
else if(buttonshowdstate==buttonstate.RIGHT_可见){
按钮操作。右键单击(viewHolder.getAdapterPosition());
}
}
ButtonShowdState=ButtonState.GONE;
currentItemViewHolder=null;
}
返回false;
}
});
}
私有void setItemsClickable(RecyclerView RecyclerView,布尔值可单击){
对于(int i=0;ipublic 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, layoutDirection);
    }

    @Override
    public void onChildDraw(Canvas c,
                            RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder,
                            float dX, float dY,
                            int actionState, 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);
                if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) dX = Math.min(dX, -buttonWidth);
                //Adding foreground layout
                getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
                        actionState, isCurrentlyActive);
            } else {
                setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        }
        if (buttonShowedState == ButtonsState.GONE) {
            //Adding foreground layout
            getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY,
                    actionState, isCurrentlyActive);
        }

    }

    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) {
                    //Adding foreground layout
                    getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, 0F, dY,
                            actionState, 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;
            }
        });
    }