簡易雷達掃描效果圖,實際效果比這個要好,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();
}
}
}