Android 自定义view完成车载可调整轨迹线

Android自定义view完成车载可调整轨迹线


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class CarView extends View implements View.OnClickListener {

    private Paint paint;
    private float[] line_r,line_l,line_1,line_2,line_3,line_t;
    //	private float line1YL,line1YR,line2YL,line2YR,line3YL,line3YR;
    public Context context;
    private float radiu;
    private boolean showPoint = false;
    private boolean cmP1=false;
    private boolean cmP2=false;
    private boolean cmP3=false;
    private boolean cmP4=false;

    private boolean cmP5=false;
    private boolean cmP6=false;

    private boolean cmP7=false;
    private boolean cmP8=false;

    private boolean cmP9=false;
    private boolean cmP10=false;
    private boolean isfirst = true;
    private boolean isMove = false;


    public final static int D_LEFT =0;
    public final static int D_RIGHT =1;

    public final static int TYPE_MIN =0;
    public final static int TYPE_MAX =1;



    public CarView(Context context) {
        this(context,null);
    }

    public CarView(Context context, AttributeSet attrs) {
        this(context,attrs,0);
    }



    public CarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }



    /**
     * 初始化控件
     */
    private void init() {
        paint = new Paint();
        /*去锯齿*/
        paint.setAntiAlias(true);
        /*设置paint的颜色*/
        paint.setColor(Color.RED);
        /*设置paint的 style*/
        paint.setStyle(Paint.Style.FILL);
        /*设置paint的外框宽度*/
        paint.setStrokeWidth(10);

        setOnClickListener(this);
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return false;
            }
        });
        setLayerType(LAYER_TYPE_HARDWARE, paint);
        radiu = 20f;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
//		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
        if(isfirst){
            line_l = new float[]{getWidth()/4,getHeight()/4,getWidth()/8,getHeight()};
            line_r = new float[]{3*getWidth()/4, getHeight()/4,7*getWidth()/8, getHeight()};
            line_1 = new float[]{getPointX(line_l, line_l[1]*2f),line_l[1]*2f,getPointX(line_r, line_r[1]*2f), line_r[1]*2f};
            line_2 = new float[]{getPointX(line_l, line_l[1]*2.5f), line_l[1]*2.5f, getPointX(line_r, line_r[1]*2.5f), line_r[1]*2.5f};
            line_3 = new float[]{getPointX(line_l, line_l[1]*3f), line_l[1]*3f, getPointX(line_r, line_r[1]*3f), line_r[1]*3f};

            isfirst = false;
        }
        int canvasWidth = canvas.getWidth();
        int canvasHeight = canvas.getHeight();
        int layerId = canvas.saveLayer(0, 0, canvasWidth, canvasHeight, null, Canvas.ALL_SAVE_FLAG);
//		paint.setXfermode(new PorterDuffXfermode(Mode.DST_OVER));
        line_t = new float[]{getPointX(line_l, line_l[1]), line_l[1], getPointX(line_r, line_r[1]), line_r[1]};

        if(showPoint){
            //四条横线
            canvas.drawLines(line_t, paint);
            paint.setPathEffect(new DashPathEffect(new float[] {20, 5}, 0));
            canvas.drawLines(line_1, paint);
            paint.setColor(Color.GREEN);
            canvas.drawLines(line_2, paint);
            paint.setColor(Color.YELLOW);
            canvas.drawLines(line_3, paint);
            paint.setColor(Color.RED);
            paint.setPathEffect(null);

            //左右两边线
            canvas.drawLines(line_l, paint);
            canvas.drawLines(line_r,  paint);


            //中间三条横线交点
            canvas.drawCircle(line_1[0], line_1[1],radiu, paint);
            canvas.drawCircle(line_1[2], line_1[3],radiu, paint);
            paint.setColor(Color.GREEN);
            canvas.drawCircle(line_2[0], line_2[1],radiu, paint);
            canvas.drawCircle(line_2[2], line_2[3],radiu, paint);
            paint.setColor(Color.YELLOW);
            canvas.drawCircle(line_3[0], line_3[1],radiu, paint);
            canvas.drawCircle(line_3[2], line_3[3],radiu, paint);
            paint.setColor(Color.RED);
            //左右四点
            canvas.drawCircle(line_l[0], line_l[1],radiu, paint);
            canvas.drawCircle(line_l[2], line_l[3],radiu, paint);

            canvas.drawCircle(line_r[0], line_r[1],radiu, paint);
            canvas.drawCircle(line_r[2], line_r[3],radiu, paint);

        }else{
            float lf=getDashLineLength(D_LEFT);
            float rf=getDashLineLength(D_RIGHT);
            canvas.drawLines(line_t, paint);
            paint.setPathEffect(new DashPathEffect(new float[] {20, 5}, 0));
            canvas.drawLine(line_1[0],line_1[1],lf,getPointY(line_1, lf), paint);
            canvas.drawLine(rf,getPointY(line_1, rf),line_1[2],line_1[3], paint);
            paint.setColor(Color.GREEN);
            canvas.drawLine(line_2[0],line_2[1],lf,getPointY(line_2, lf), paint);
            canvas.drawLine(rf,getPointY(line_2, rf),line_2[2],line_2[3], paint);
            paint.setColor(Color.YELLOW);
            canvas.drawLine(line_3[0],line_3[1],lf,getPointY(line_3, lf), paint);
            canvas.drawLine(rf,getPointY(line_3, rf),line_3[2],line_3[3], paint);
            paint.setPathEffect(null);
            paint.setColor(Color.RED);
            //左右两边线
            canvas.drawLines(line_l, paint);
            canvas.drawLines(line_r,  paint);
            canvas.drawCircle(line_l[0], line_l[1],paint.getStrokeWidth()/2, paint);
            canvas.drawCircle(line_r[0], line_r[1],paint.getStrokeWidth()/2, paint);
        }
//		paint.setStyle(Paint.Style.STROKE);
        paint.setColor(Color.RED);
        paint.setPathEffect(null);
        paint.setXfermode(null);
        canvas.restoreToCount(layerId);
    }
    /**
     * 获取坐标x
     * @param line 直线坐标系
     * @param y y点
     * @return
     */
    private float getPointX(float[] line,float y){
        float x = 0;
//		Log.d("chr", "line====>"+line.length+":::y====>"+y);
        float x1 = line[0];
        float y1 = line[1];
        float x2 = line[2];
        float y2 = line[3];
        x = ((y-y1)/(y2-y1))*(x2-x1)+x1;
        return x;
    }
    /**
     * 获取坐标y
     * @param line:直线坐标系
     * @param x:x点
     * @return
     */

    private float getPointY(float[] line,float x){
        float y = 0;
//		Log.d("chr", "line====>"+line.length+":::y====>"+y);
        float x1 = line[0];
        float y1 = line[1];
        float x2 = line[2];
        float y2 = line[3];
        y = ((x-x1)/(x2-x1))*(y2-y1)+y1;

        return y;
    }
    /**
     * 获取点应该移动到的Y坐标
     * @param line:线段坐标
     * @param y:滑动时的y坐标
     * @return
     */

    private float getMoveY(float[] line,float y){

        if(y<=line[1]+ radiu){
            y=line[1]+radiu*2.0f;
        }

        if(y>=line[3]-radiu*2.0f){
            y=line[3]-radiu*2.0f;
        }

        return y;
    }

    /**
     *
     * @param direction 获取虚线长度
     * @return
     */
    private float getDashLineLength(int direction){
        float length = 0;
        int a = 20;
        switch (direction) {
            case D_LEFT:
                length = line_t[0]+(line_t[2]-line_t[0])/a;
                break;
            case D_RIGHT:
                length = line_t[0]+(a-1)*(line_t[2]-line_t[0])/a;
                break;
        }
        return length;
    }

    /**
     * 获取最小值
     * @return
     */
    private float getMinPoint(float point[]){
        float min = point[0];
        for(int i=0;i<point.length;i++){
            if(min>point[i]){
                min=point[i];
            }
        }
        return min;
    }

    /**
     * 获取最大值
     * @return
     */
    private float getMaxPoint(float point[]){
        float max = point[0];
        for(int i=0;i<point.length;i++){
            if(max<point[i]){
                max=point[i];
            }
        }
        return max;
    }
    /**
     * 获取y轴限制点
     * @param point
     * @param y
     * @param type
     * @return
     */
    private float getLimtMoveY(float point[],float y,int type){

        if(type == TYPE_MIN){
            float limt = getMinPoint(point);
            if(y>limt-radiu*2.0f){
                y = limt-radiu*2.0f;
            }
        }
        if(type == TYPE_MAX){
            float limt2 = getMaxPoint(point);
            if(y<limt2+radiu*2.0f){
                y = limt2+radiu*2.0f;
            }
        }

        return y;
    }


    public void proofView(int direction){
        switch (direction) {
            case D_LEFT:
                line_1[3] = line_1[1];
                line_1[2] = getPointX(line_r, line_1[1]);

                line_2[3] = line_2[1];
                line_2[2] = getPointX(line_r, line_2[1]);

                line_3[3] = line_3[1];
                line_3[2] = getPointX(line_r, line_3[1]);

                break;

            case D_RIGHT:
                line_1[1] = line_1[3];
                line_1[0] = getPointX(line_l, line_1[3]);

                line_2[1] = line_2[3];
                line_2[0] = getPointX(line_l, line_2[3]);

                line_3[1] = line_3[3];
                line_3[0] = getPointX(line_l, line_3[3]);

                break;
        }

        invalidate();
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        float x =event.getX();
        float y =event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if(showPoint){
                    isMove = false;
                    Log.d("chr", "MotionEvent.ACTION_DOWN::x====>"+x+"::::y===>"+y);
                    if(x<=(line_l[0]+radiu*2.0f)
                            && x>=(line_l[0]-radiu*2.0f)
                            && y>=(line_l[1]-radiu*2.0f)
                            &&y<=(line_l[1]+radiu*2.0f)){
                        cmP1 = true;
                    }
                    else if(x<=(line_r[0]+radiu*2.0f)
                            && x>=(line_r[0]-radiu*2.0f)
                            && y>=(line_r[1]-radiu*2.0f)
                            &&y<=(line_r[1]+radiu*2.0f)){
                        cmP2 = true;
                    }else if(x<=(line_l[2]+radiu*2.0f )
                            && x>=(line_l[2]-radiu*2.0f)
                            && y>=(line_l[3]-radiu*2.0f)
                            &&y<=(line_l[3]+radiu*2.0f)){
                        cmP3 = true;
                    }else if(x<=(line_r[2]+radiu*2.0f )
                            && x>=(line_r[2]-radiu*2.0f)
                            && y>=(line_r[3]-radiu*2.0f)
                            &&y<=(line_r[3]+radiu*2.0f)){
                        cmP4 = true;
                    }else if(x<=(line_1[0]+radiu*2.0f )
                            && x>=(line_1[0]-radiu*2.0f)
                            && y>=(line_1[1]-radiu*2.0f)
                            &&y<=(line_1[1]+radiu*2.0f)){
                        cmP5 = true;
                    }else if(x<=(line_1[2]+radiu*2.0f )
                            && x>=(line_1[2]-radiu*2.0f)
                            && y>=(line_1[3]-radiu*2.0f)
                            &&y<=(line_1[3]+radiu*2.0f)){
                        cmP6 = true;
                    }else if(x<=(line_2[0]+radiu*2.0f )
                            && x>=(line_2[0]-radiu*2.0f)
                            && y>=(line_2[1]-radiu*2.0f)
                            &&y<=(line_2[1]+radiu*2.0f)){
                        cmP7 = true;
                    }else if(x<=(line_2[2]+radiu*2.0f)
                            && x>=(line_2[2]-radiu*2.0f)
                            && y>=(line_2[3]-radiu*2.0f)
                            &&y<=(line_2[3]+radiu*2.0f)){
                        cmP8 = true;
                    }else if(x<=(line_3[0]+radiu *2.0f)
                            && x>=(line_3[0]-radiu*2.0f)
                            && y>=(line_3[1]-radiu*2.0f)
                            &&y<=(line_3[1]+radiu*2.0f)){
                        cmP9 = true;
                    }else if(x<=(line_3[2]+radiu*2.0f )
                            && x>=(line_3[2]-radiu*2.0f)
                            && y>=(line_3[3]-radiu*2.0f)
                            &&y<=(line_3[3]+radiu*2.0f)){
                        cmP10 = true;
                    }
                }

                break;

            case MotionEvent.ACTION_MOVE:
                float[] point_L = new float[]{line_1[1],line_2[1],line_3[1]};
                float[] point_R = new float[]{line_1[3],line_2[3],line_3[3]};
                if(cmP1){
                    isMove = true;

                    line_l[0] =x;
                    line_l[1] =getLimtMoveY(point_L, y, TYPE_MIN);
                    line_1[0]= getPointX(line_l,line_1[1]);
                    line_2[0]= getPointX(line_l,line_2[1]);
                    line_3[0]= getPointX(line_l,line_3[1]);
                }else if(cmP2){
                    isMove = true;
                    line_r[0] = x;
                    line_r[1] = getLimtMoveY(point_R, y, TYPE_MIN);
                    line_1[2]= getPointX(line_r,line_1[3]);
                    line_2[2]= getPointX(line_r,line_2[3]);
                    line_3[2]= getPointX(line_r,line_3[3]);
                }else if(cmP3){
                    isMove = true;
                    line_l[2] =x;
                    line_l[3] =getLimtMoveY(point_L, y, TYPE_MAX);
                    line_1[0]= getPointX(line_l,line_1[1]);
                    line_2[0]= getPointX(line_l,line_2[1]);
                    line_3[0]= getPointX(line_l,line_3[1]);
                }else if(cmP4){
                    isMove = true;
                    line_r[2] = x;
                    line_r[3] = getLimtMoveY(point_R, y, TYPE_MAX);
                    line_1[2]= getPointX(line_r,line_1[3]);
                    line_2[2]= getPointX(line_r,line_2[3]);
                    line_3[2]= getPointX(line_r,line_3[3]);
                }else if(cmP5){
                    isMove = true;
                    y=getMoveY(line_l,y);
                    line_1[0]= getPointX(line_l, y);
                    line_1[1]= y;
                }else if(cmP6){
                    isMove = true;
                    y=getMoveY(line_r,y);
                    line_1[2]= getPointX(line_r, y);
                    line_1[3]= y;
                }else if(cmP7){
                    isMove = true;
                    y=getMoveY(line_l,y);
                    line_2[0]= getPointX(line_l, y);
                    line_2[1]= y;
                }else if(cmP8){
                    isMove = true;
                    y=getMoveY(line_r,y);
                    line_2[2]= getPointX(line_r, y);
                    line_2[3]= y;
                }else if(cmP9){
                    isMove = true;
                    y=getMoveY(line_l,y);
                    line_3[0]= getPointX(line_l, y);
                    line_3[1]= y;
                }else if(cmP10){
                    isMove = true;
                    y=getMoveY(line_r,y);
                    line_3[2]= getPointX(line_r, y);
                    line_3[3]= y;
                }
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                cmP1= false;
                cmP2= false;
                cmP3= false;
                cmP4= false;

                cmP5= false;
                cmP6= false;

                cmP7= false;
                cmP8= false;

                cmP9= false;
                cmP10= false;
                if(!isMove)
                    showPoint = !showPoint;
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }


    @Override
    public void onClick(View v) {
    }


}

参考地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值