前幾天我的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); // 調用自身 重複繪製
}
};
}