Android 自定义View实现可拖动边框缩放的矩形

先看效果图

我的思路是,首先我给确定下来我点击的是哪一条边,这个可以用onTouchEvent来监听实现。然后,由于用户很难精确的点击到边上,所有点击时需要存在一定的误差范围。最后,我需要判断每条边的边界情况,例如右边框不能移动到左边框的左边,上边框不能移动到下边框的下面等。

下面是自定义View的源码:

public class MyRectView extends View {
    private Paint paint;
    private Rect rect;
    private int left=200,right=700,top=200,bottom=500;
    private int strokeWidth=10;
    private boolean onVerticalLeftStroke=false,onVerticalRightStroke=false; //是否在左边框上;右边框上
    private boolean onHorizontalUpStroke=false,onHorizontalDownStroke=false;//是否在上边框上;下边框上
    private float currentX=0,currentY=0;
    public MyRectView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init(){
        paint=new Paint();
        paint.setStrokeWidth(strokeWidth);
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.STROKE);
        rect=new Rect(left,top,right,bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawRect(rect,paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x=event.getX();
        float y=event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                currentX=x;currentY=y;
                onHorizontalRectStroke(x,y);
                onVerticalRectStroke(x,y);
                break;
            case MotionEvent.ACTION_MOVE:
                currentX=x;currentY=y;
                moveRectStroke();
                break;
            case MotionEvent.ACTION_UP:
                onHorizontalUpStroke=false;
                onHorizontalDownStroke=false;
                onVerticalLeftStroke=false;
                onVerticalRightStroke=false;
                break;
        }
        return true;
    }

    //通过边框移动矩形(重画)
    private void moveRectStroke(){
        if(onVerticalLeftStroke){
            left=(int)currentX;
            //检查左边框的边界
            if(left<0)left=0;
            if(left>right-25)left=right-25;
            redrawRect();
        }else if(onVerticalRightStroke){
            right=(int)currentX;
            //检查右边框的边界
            if(right>Constants.SCREEN_WIDTH)right=900;
            if(right<left+25)right=left+25;
            redrawRect();
        }else if(onHorizontalUpStroke){
            top=(int)currentY;
            //检查上边框的边界
            if(top<0)top=0;
            if(top>bottom-25)top=bottom-25;
            redrawRect();
        }else if(onHorizontalDownStroke){
            bottom=(int)currentY;
            //检查下边框的边界
            if(bottom>Constants.SCREEN_HEIGHT)bottom=1500;
            if(bottom<top+25)bottom=top+25;
            redrawRect();
        }
    }

    //重绘矩形
    private void redrawRect(){
        rect.set(left,top,right,bottom);
        invalidate();
    }

    //是否在矩形边框上
    private void onVerticalRectStroke(float x,float y){
        //在竖边框上
        if(y>=top && y<=bottom){
            //在左边框上(在一定的误差范围内)
            if(x<=left+strokeWidth*5 && x>=left-strokeWidth*5){
                onVerticalLeftStroke=true;
            }
            //在右边框上(在一定的误差范围内)
            else if(x<=right+strokeWidth*5 && x>=right-strokeWidth*5){
                onVerticalRightStroke=true;
            }
        }
    }

    //是否在矩形边框上
    private void onHorizontalRectStroke(float x,float y){
        //在横边框上
        if(x>=left && x<=right){
            //在上边框上(在一定的误差范围内)
            if(y<=top+strokeWidth*5 && y>=top-strokeWidth*5){
                onHorizontalUpStroke=true;
            }
            //在下边框上(在一定的误差范围内)
            else if(y<=bottom+strokeWidth*5 && y>=bottom-strokeWidth*5) {
                onHorizontalDownStroke=true;
            }
        }
    }
}

Activity类:

public class MyRectAct extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_rect);
    }
}

xml布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <com.hualinfo.myviewtext.MyRectView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/zz51233273/article/details/107629079