自定义View-简易雷达扫描

简易雷达扫描效果图,实际效果比这个要好,gif生成时或者网页渲染这个gif有点问题。
在这里插入图片描述

原理:

  • drawCircle画2个同心圆 内圆和外圆
  • drawLine画2条直径,水平和垂直的
  • drawArc画弧
    • 起始角度每次增大4°,从0°开始。
    • 每次画弧的起始角度相对于上一次增大4°,通过旋转座标系来实现,开始为0°,360°后转为0°. 保存初始座标系,旋转后恢复到开始的座标系(3点钟为0°方向)
    • 每次画弧的终点角度相对于上一次增大4°,直到360°后由重0°开始
    • 弧的画笔通过SweepGradient设置渐变色
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;


public class RadarScanView extends View {

    private static final int MSG_RUN = 1;

    private int mCircleColor = Color.BLACK;
    private int mLineColor = Color.BLACK;
    private int mArcColor = Color.WHITE;
    private int mArcStartColor = Color.WHITE;
    private int mArcEndColor = Color.TRANSPARENT;

    private Paint mCirclePaint; // 绘制圆形画笔
    private Paint mArcPaint; // 绘制扇形画笔
    private Paint mLinePaint; // 绘制线条画笔

    private RectF mRectF;

    private int mSweep; // 扇形角度

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

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

    }

    public RadarScanView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    /**
     * 初始化
     */
    private void init(Context context){
        mCircleColor = context.getResources().getColor(R.color.radar_begin_color);
        mArcColor = context.getResources().getColor(R.color.radar_begin_color);
        mLineColor = context.getResources().getColor(R.color.radar_begin_color);

        mArcStartColor = context.getResources().getColor(R.color.radar_begin_color);
        mArcEndColor = context.getResources().getColor(android.R.color.transparent);

        //抗锯齿
        mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mCirclePaint.setColor(mCircleColor);
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setStrokeWidth(1.f);


        mArcPaint.setColor(mArcColor);
        mArcPaint.setStyle(Paint.Style.FILL);

        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setColor(mLineColor);
        mLinePaint.setStrokeWidth(1.f);

        mRectF = new RectF();
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int size = getMeasuredWidth();
        setMeasuredDimension(size, size);
        mRectF.set(0, 0, getMeasuredWidth(), getMeasuredHeight());

        mArcPaint.setShader(new SweepGradient(size / 2, size / 2, mArcStartColor, mArcEndColor));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int centerX = getMeasuredWidth() / 2;
        int centerY = getMeasuredHeight() / 2;

        //保存当前状态
        canvas.save();
        //选择座标系
        canvas.rotate(mSweep, centerX, centerY);
        //画圆弧
        canvas.drawArc(mRectF, 0, mSweep, true, mArcPaint);
        //恢复到上次保存的状态,这样的结果每次座标系起点都是3点钟方向,因为mSweep初始为0
        canvas.restore();

        canvas.drawLine(0, centerY, getMeasuredWidth(), centerY, mLinePaint);
        canvas.drawLine(centerX, 0, centerX, getMeasuredHeight(), mLinePaint);

        canvas.drawCircle(centerX, centerY, centerX / 2, mCirclePaint);
        canvas.drawCircle(centerX, centerY, centerX, mCirclePaint);

    }

    private boolean swicth = true;
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == MSG_RUN) {
                mSweep+=4;
                if(mSweep > 360) mSweep = 0;
                postInvalidate();
//                sendEmptyMessage(MSG_RUN);
                if (swicth){
                    sendEmptyMessageDelayed(MSG_RUN, 50);
                }
            }
        }
    };

    /**
     * 开始扫描的方法
     */
    public void startScan(){
        if(mHandler != null){
            swicth = true;
            mHandler.obtainMessage(MSG_RUN).sendToTarget();
        }
    }
 	 /**
     * 停止扫描
     */
    public void stopScan(){
        if(mHandler != null){
            swicth = false;
            mHandler.obtainMessage(MSG_RUN).sendToTarget();
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章