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();
    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容