3.挖掘机,随车吊自定义View汇总

先看效果图


效果图

如效果图所示主要包括四个自定义View:挖掘机工作装置姿态、车体的左右和前后倾角、车身的回转角度、随车吊。
其中挖掘机工作装置的姿态已经在以前的文章中介绍过。


前后左右倾角和回转角度控件效果图

前后左右倾角控件主要涉及到圆弧角度的转换和圆弧的绘图方法,车体法线的角度变换,前后的倾角分别用浅绿色和浅蓝色区域标识,浅绿色区域越多表示车体后倾角度越大。法线左右偏移越大表示左右倾斜越大。主要涉及到的知识点是画笔Paint、Matrix、Path、DashPathEffect、drawArc、drawText的使用。
回转角度的控件,主要是中间类似车体的图片描绘,看似是矩形,其实利用设置画笔的setStrokeWidth()进行画线操作。
前后左右倾角控件和回转角度的控件十分类似。

随车吊控件主要确定如图所示的关键点


随车吊控件关键点

从左到右依次是吊臂轴心旋转点,吊臂第一节结束点,吊臂第二节结束点,吊臂第二节预留长度点,吊臂末端结束点,最下面一点是与挂钩连接的点。
吊臂的旋转与伸缩都是通过对以上几个点的Matrix的旋转和平移变换得到,最后进行drawLine。吊钩的位置通过计算与挂钩连接点的距离确定。

前后左右倾角控件关键代码

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //画外框的⚪
        mPaint.setStyle(Paint.Style.STROKE);
        DashPathEffect effects1 = new DashPathEffect(new float[] { 2, 2}, 1);
        mPaint.setPathEffect(effects1);
        canvas.drawCircle(centerXY,centerXY,radiusOutSide,mPaint);
        //画水平线
        Path horLinePath = new Path();
        horLinePath.moveTo(pointStart[0],pointStart[1]);
        horLinePath.lineTo(pointEnd[0],pointEnd[1]);
        canvas.drawPath(horLinePath , horLinePaint);

        //画左右倾斜线
        lineMatrix.reset();
        //计算旋转角度
        lineMatrix.setRotate(calLRAngle(lrSlope),centerXY,centerXY);
        lineMatrix.mapPoints(pointSpinStart,pointStart);
        lineMatrix.mapPoints(pointSpinEnd,pointEnd);
        canvas.drawLine(pointSpinStart[0],pointSpinStart[1],pointSpinEnd[0],pointSpinEnd[1],paintLR);

        paintLR.setStyle(Paint.Style.FILL);
        canvas.drawCircle(pointSpinStart[0],pointSpinStart[1],5,paintLR);


        Path verLinePath = new Path();
        verLinePath.moveTo(centerXY,centerXY);
        verLinePath.lineTo(pointSpinStart[0],pointSpinStart[1]);
        canvas.drawPath(verLinePath , verLinePaint);
        Path verLinePath1 = new Path();
        verLinePath1.moveTo(centerXY,centerXY);
        verLinePath1.lineTo(pointSpinEnd[0],pointSpinEnd[1]);
        canvas.drawPath(verLinePath1 , verLinePaint);

        //画前后倾角
        FBShopePara fbShopePara = calFBAngle(fbSlope);
        canvas.drawArc(rectFOval,fbShopePara.fStartAngle+lrSlope,fbShopePara.fSweepAngle,false,paintFOval);
        canvas.drawArc(rectFOval,fbShopePara.bStartAngle+lrSlope,fbShopePara.bSweepAngle,false,paintBOval);

        //画圆心
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(centerXY,centerXY,3,mPaint);

        //画text
        drawText(canvas);

//        changeLRAngle();
//        changeFBAngle();
//        invalidate();


    }

    //计算左右角度
    private float calLRAngle(float lrSlope){
        //private double lrSlope;//左右的倾角 -90.0~90.0度
        //左是负数 右边是正数
        //转换成绕圆形旋转的度数
        return (float) (90.0+lrSlope);
    }
    //计算前后角度
    private FBShopePara calFBAngle(float fbSlope){
        FBShopePara para = new FBShopePara();
        //fbSlope = fbSlope*2;//-90+90

        //前倾负数的角度
        //后倾是正的角度
        para.fStartAngle = -(180+fbSlope);
        para.fSweepAngle = (180+2*fbSlope);
        para.bStartAngle = fbSlope;
        para.bSweepAngle = 180-2*fbSlope;

        return para;
    }


    class FBShopePara{
        float fStartAngle;
        float fSweepAngle;
        float bStartAngle;
        float bSweepAngle;
    }

回转角度控件关键代码

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画外框的⚪
        int strokeWidth = SizeUtils.dp2px(3);
        paintCircle.setStrokeWidth(strokeWidth);
        paintCircle.setStyle(Paint.Style.STROKE);
        DashPathEffect effects1 = new DashPathEffect(new float[] { 2, 2}, 1);
        paintCircle.setPathEffect(effects1);
        canvas.drawCircle(centerXY,centerXY,radiusOutSide,paintCircle);

        //画水平和竖直线
        paintCircle.setStrokeWidth(1);
        canvas.drawLine(
                pointStart[0],
                pointStart[1],
                pointEnd[0],
                pointEnd[1],
                paintCircle
                );
        canvas.drawLine(
                pointSpinStart[0],
                pointSpinStart[1],
                pointSpinEnd[0],
                pointSpinEnd[1],
                paintCircle
                );

        rotateMatrix.reset();
        rotateMatrix.setRotate(slewAngle,centerXY,centerXY);
        rotateMatrix.mapPoints(pointSpinBoom1End,pointBoom1End);
        rotateMatrix.mapPoints(pointSpinBoom2End,pointBoom2End);
        rotateMatrix.mapPoints(pointSpinCabStart,pointCabStart);
        rotateMatrix.mapPoints(pointSpinCabEnd,pointCabEnd);
        rotateMatrix.mapPoints(pointSpinEqueStart,pointEqueStart);
        rotateMatrix.mapPoints(pointSpinEqueEnd,pointEqueEnd);
        rotateMatrix.mapPoints(pointSpinBackStart,pointBackStart);
        rotateMatrix.mapPoints(pointSpinBackEnd,pointBackEnd);

        //画动臂
        paintYellow.setStrokeWidth(SizeUtils.dp2px(10));
        canvas.drawLine(centerXY,centerXY,pointSpinBoom1End[0],pointSpinBoom1End[1],paintYellow);
        paintBlack.setStrokeWidth(SizeUtils.dp2px(10));
        canvas.drawLine(pointSpinBoom1End[0],pointSpinBoom1End[1],pointSpinBoom2End[0],pointSpinBoom2End[1],paintBlack);
        //画驾驶室
        paintBlack.setStrokeWidth(SizeUtils.dp2px(15));
        canvas.drawLine(pointSpinCabStart[0],pointSpinCabStart[1],pointSpinCabEnd[0],pointSpinCabEnd[1],paintBlack);
        //画工作装置根区域
        canvas.drawLine(pointSpinEqueStart[0],pointSpinEqueStart[1],pointSpinEqueEnd[0],pointSpinEqueEnd[1],paintYellow);
        //画配重区域
        paintYellow.setStrokeWidth(SizeUtils.dp2px(25));
        canvas.drawLine(pointSpinBackStart[0],pointSpinBackStart[1],pointSpinBackEnd[0],pointSpinBackEnd[1],paintYellow);
        //画圆心
        paintCircle.setStyle(Paint.Style.FILL);
        canvas.drawCircle(centerXY,centerXY,3,paintCircle);


        //书写角度
        drawText(canvas);

//        changeAngle();
//        invalidate();

    }

随车吊控件关键代码

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.BLUE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(1);
        //canvas.drawRect(new Rect(0,0,SizeUtils.dp2px(320),SizeUtils.dp2px(320)),paint);

        //画吊臂
        paintYellow.setStrokeWidth(SizeUtils.dp2px(22));
        canvas.drawLine(centerXo,centerYo,pointSpin1[0],pointSpin1[1],paintYellow);
        paintBlack.setStrokeWidth(SizeUtils.dp2px(18));
        canvas.drawLine(pointSpin1[0],pointSpin1[1],pointSpin3[0],pointSpin3[1],paintBlack);
        paintBlack.setStrokeWidth(SizeUtils.dp2px(26));
        canvas.drawLine(pointSpin3[0],pointSpin3[1],pointSpin4[0],pointSpin4[1],paintBlack);


        //画车体
        canvas.drawBitmap(bitmapBody,rectBody,rectFBody,paintBody);
        //画吊绳
        paintBlackLine.setStrokeWidth(SizeUtils.dp2px(1));
        canvas.drawLine(pointSpin5[0],pointSpin5[1],pointSpin5[0],rectFHook.top,paintBlackLine);
        //画吊钩
        canvas.drawBitmap(bitmapHook,rectHook,rectFHook,paintBody);

        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setColor(Color.RED);
        //旋转的轴心选择,尝试的两个点
//        canvas.drawCircle(centerX,centerY,5,paint);
//        canvas.drawCircle(centerX,centerY-SizeUtils.dp2px(20),5,paint);
        //画关键点
        canvas.drawCircle(centerX+SizeUtils.dp2px(20),centerY-SizeUtils.dp2px(20),5,paint);
        canvas.drawCircle(pointSpin1[0],pointSpin1[1],5,paint);
        canvas.drawCircle(pointSpin2[0],pointSpin2[1],5,paint);
        canvas.drawCircle(pointSpin3[0],pointSpin3[1],5,paint);
        canvas.drawCircle(pointSpin4[0],pointSpin4[1],5,paint);
        canvas.drawCircle(pointSpin5[0],pointSpin5[1],5,paint);


    }


    public void setPara(float angleCrane,float lengthCrane,float heightCrane){
        Matrix matrix = new Matrix();
        //先平移
        matrix.preTranslate((lengthCrane-100)*SizeUtils.dp2px(100)/100,0);

        //再旋转
        matrix.postRotate(0-angleCrane,centerXo,centerYo);


        matrix.mapPoints(pointSpin2,point2);
        matrix.mapPoints(pointSpin3,point3);
        matrix.mapPoints(pointSpin4,point4);
        matrix.mapPoints(pointSpin5,point5);

        matrix.reset();
        matrix.setRotate(0-angleCrane,centerXo,centerYo);
        matrix.mapPoints(pointSpin1,point1);


        //钩子的位置
        //目前的最长距离
        float distance = point5[1]-pointSpin5[1];
        //100最上面
        //0最下面
        float distanceY = pointSpin5[1]+(100-heightCrane)*distance/100;
        rectFHook =        rectFHook = new RectF(
                pointSpin5[0]- SizeUtils.dp2px(10.5f),
                distanceY,
                pointSpin5[0]+ SizeUtils.dp2px(10.5f),
                distanceY+ SizeUtils.dp2px(33f)
        );

        invalidate();
    }

你可能感兴趣的:(3.挖掘机,随车吊自定义View汇总)