Android:自定義view 實現雷達掃描效果

前幾天我的app上加了一個雷達掃描來查詢附件商家的效果。看起來還是挺不錯的,現在把雷達掃描的效果分享給大家。

最近項目新版剛上線,不是很忙,所以多抽出了一些時間來整理一下博客。

那書歸正傳:

先上效果圖
請原諒我的失真

圖片有點失真,不要介意,先介紹下,主要用了Paint(畫筆)+ canvas(畫布) (以後我會專門寫一篇文章來介紹paint和canvas,這裏先認爲大家都懂得paint和canvas的相關知識)

先看圖,主要有幾個點需要完成:

1.背景有五個半徑不同的園。
2.類似於掃描的渲染效果。
3.讓整個佈局轉起來。

好,咱們一個一個來。
第一個比較簡單,用paint在canvas畫五個大小不一的圓。
第二個用SweepGradient 增加渲染效果。
第三個讓canvas的矩陣旋轉變換。

下面直接上代碼,註釋比較全就不在多加修飾了。

/**
 * 雷達掃描 自定義view
 *
 * @author Bihaidong
 * @date 2016-9-18 9:46:09
 */
public class CustomView extends View {

    private int mWidth, mHeight;

    private float[] pots = {0.05f, 0.1f, 0.15f, 0.2f, 0.25f};

    private Shader scanShader; // 掃描渲染shader
    private Matrix matrix = new Matrix(); // 旋轉需要的矩陣
    private int scanSpeed = 5; // 掃描速度
    private int scanAngle; // 掃描旋轉的角度

    private Paint mPaintCircle; // 畫圓用到的paint
    private Paint mPaintRadar; // 掃描用到的paint


    public CustomView(Context context) {
        super(context);

        // 畫圓用到的paint
        mPaintCircle = new Paint();
        mPaintCircle.setStyle(Paint.Style.STROKE); // 描邊
        mPaintCircle.setStrokeWidth(1); // 寬度
        mPaintCircle.setAlpha(100); // 透明度
        mPaintCircle.setAntiAlias(true); // 抗鋸齒
        mPaintCircle.setColor(Color.parseColor("#B0C4DE")); // 設置顏色 亮鋼蘭色

        // 掃描用到的paint
        mPaintRadar = new Paint();
        mPaintRadar.setStyle(Paint.Style.FILL_AND_STROKE); // 填充
        mPaintRadar.setAntiAlias(true); // 抗鋸齒

        post(run);
    }

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

        for (int i = 0; i < pots.length; i++) {
            canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth * pots[i], mPaintCircle);
        }

        // 畫布的旋轉變換 需要調用save() 和 restore()
        canvas.save();

        scanShader = new SweepGradient(mWidth / 2, mHeight / 2,
                new int[]{Color.TRANSPARENT, Color.parseColor("#84B5CA")}, null);
        mPaintRadar.setShader(scanShader); // 設置着色器
        canvas.concat(matrix);
        canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth * pots[4], mPaintRadar);

        canvas.restore();
    }

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

        // 取屏幕的寬高是爲了把雷達放在屏幕的中間
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        mWidth = mHeight = Math.min(mWidth, mHeight);
    }

    private Runnable run = new Runnable() {
        @Override
        public void run() {
            scanAngle = (scanAngle + scanSpeed) % 360; // 旋轉角度 對360取餘
            matrix.postRotate(scanSpeed, mWidth / 2, mHeight / 2); // 旋轉矩陣
            invalidate(); // 通知view重繪
            postDelayed(run, 130); // 調用自身 重複繪製
        }
    };
}
發佈了46 篇原創文章 · 獲贊 34 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章