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

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