android最新扫描,Android下实现雷达扫描效果(学习)

Android UI

前几天看见一篇文章Android 雷达扫描动画效果实现 就学习了一下,在此做了笔记并做了一些修改

自定义ScanRadar继承了View控件

初始化几个画笔

private void initPaint() {

//用来绘画直线的画笔

mPaintLine = new Paint(Paint.ANTI_ALIAS_FLAG); // 消除锯齿

mPaintLine.setAntiAlias(true);

mPaintLine.setColor(Color.WHITE);

mPaintLine.setStyle(Style.STROKE);

mPaintLine.setStrokeWidth(5);

//用来绘画背景圆的画笔

mPaintCircle = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintCircle.setAntiAlias(true);

mPaintCircle.setColor(0x99000000);

//实心圆style

mPaintCircle.setStyle(Style.FILL);

//绘画圆渐变色的画笔

mPaintSector = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintSector.setAntiAlias(true);

mPaintSector.setStyle(Style.FILL);

//绘画实点

mPaintPoint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintPoint.setAntiAlias(true);

mPaintPoint.setColor(Color.WHITE);

mPaintPoint.setStyle(Style.FILL);

}

重写了onMeasure函数,在此函数中获得控件的宽度作为雷达的直径

//重写onMeasure

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//获得控件的宽度 宽度<=高度

viewSize = getMeasuredWidth();

//初始化一个颜色渲染器

SweepGradient shader = new SweepGradient(viewSize /2.0f, viewSize/2.0f, Color.TRANSPARENT, Color.GREEN);

//mPaintSector设置颜色渐变渲染器

mPaintSector.setShader(shader);

}

然后重写onDraw函数

@Override

protected void onDraw(Canvas canvas) {

//绘制背景圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintCircle);

//绘制空心圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/4.0f, mPaintLine);

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/8.0f, mPaintLine);

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintLine);

//绘制水平垂直两个直径

canvas.drawLine(0, viewSize/2.0f,viewSize, viewSize/2.0f, mPaintLine);

canvas.drawLine(viewSize/2.0f,0,viewSize/2.0f,viewSize, mPaintLine);

//可以用来显示实心点,使用了接口让外面调用

if(mListener != null){

mListener.OnUpdate(canvas,mPaintPoint,viewSize/2.0f,viewSize/2.0f,viewSize/2.0f);

}

//把画布的多有对象与matrix联系起来

if(matrix != null){

canvas.concat(matrix);

}

//绘制颜色渐变圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintSector);

super.onDraw(canvas);

}

ef560fe3eea8

此时的效果显示

然后剩下动画更新了

在这使用了一个线程来更新界面展示

class ScanThread extends Thread{

private View view;

public ScanThread(View view) {

super();

this.view = view;

}

@Override

public void run() {

while(isRunning){

if(isStart){

start += 1;

view.post(new Runnable() {

@Override

public void run() {

//创建一个矩阵

matrix = new Matrix();

//矩阵设置旋转

matrix.preRotate(start*direction, viewSize/2.0f, viewSize/2.0f);

//重画

view.invalidate();

}

});

try {

Thread.sleep(5);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

// 需要注意的是,线程的结束和开启是使用了两个boolean的变量来控制

isRunning ,isStart分别表示了线程的状态

view.post(Runable);函数的作用是

Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.

意思就是任务会放到ui线程里执行

最后 暴露出一个接口让外界更新发现的目标显示

public OnPointUpdateListener mListener;

//更新point的接口

public interface OnPointUpdateListener{

//onDraw中的画布,paintPoint绘制实心点的画笔,cx,cy,radius 雷达的圆心坐标,半径

public void OnUpdate(Canvas canvas,Paint paintPoint,float cx,float cy,float radius);

}

public void setOnPointUpdateListener(OnPointUpdateListener listener){

this.mListener = listener;

}

然后贴出完整的代码

package com.linge.scanradar.view.radar;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.SweepGradient;

import android.graphics.Paint.Style;

import android.util.AttributeSet;

import android.view.View;

public class ScanRadar extends View {

//控件宽度<=高度 //雷达直径

private float viewSize;

//画笔

private Paint mPaintSector;

private Paint mPaintCircle;

private Paint mPaintLine;

private Paint mPaintPoint;

//线程是否在执行

private boolean isRunning = false;

//任务是否已经开始

private boolean isStart = false;

//记录并设置旋转角度

private int start = 0;

//雷达旋转方向

//顺时针

public final static int CLOCK_WISE = 1;

//逆时针

public final static int ANSI_CLOCK_WISE = -1;

public final static int DEFAULT_DIRECTION = CLOCK_WISE;

private int direction = DEFAULT_DIRECTION;

private ScanThread scanThread; //线程

private Matrix matrix; //矩阵

public ScanRadar(Context context, AttributeSet attrs) {

this(context, attrs,0);

}

public ScanRadar(Context context) {

this(context,null);

}

public ScanRadar(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initPaint();

}

private void initPaint() {

//用来绘画直线的画笔

mPaintLine = new Paint(Paint.ANTI_ALIAS_FLAG); // 消除锯齿

mPaintLine.setAntiAlias(true);

mPaintLine.setColor(Color.WHITE);

mPaintLine.setStyle(Style.STROKE);

mPaintLine.setStrokeWidth(5);

//用来绘画背景圆的画笔

mPaintCircle = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintCircle.setAntiAlias(true);

mPaintCircle.setColor(0x99000000);

//实心圆style

mPaintCircle.setStyle(Style.FILL);

//绘画圆渐变色的画笔

mPaintSector = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintSector.setAntiAlias(true);

mPaintSector.setStyle(Style.FILL);

//绘画实点

mPaintPoint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaintPoint.setAntiAlias(true);

mPaintPoint.setColor(Color.WHITE);

mPaintPoint.setStyle(Style.FILL);

}

@Override

protected void onDraw(Canvas canvas) {

//绘制背景圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintCircle);

//绘制空心圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/4.0f, mPaintLine);

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/8.0f, mPaintLine);

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintLine);

//绘制水平垂直两个直径

canvas.drawLine(0, viewSize/2.0f,viewSize, viewSize/2.0f, mPaintLine);

canvas.drawLine(viewSize/2.0f,0,viewSize/2.0f,viewSize, mPaintLine);

//显示实心点

if(mListener != null){

mListener.OnUpdate(canvas,mPaintPoint,viewSize/2.0f,viewSize/2.0f,viewSize/2.0f);

}

//把画布的多有对象与matrix联系起来

if(matrix != null){

canvas.concat(matrix);

}

//绘制颜色渐变圆

canvas.drawCircle(viewSize/2.0f,viewSize/2.0f, viewSize/2.0f, mPaintSector);

super.onDraw(canvas);

}

//重写onMeasure

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//获得控件的宽度 宽度<=高度

viewSize = getMeasuredWidth();

//初始化一个颜色渲染器

SweepGradient shader = new SweepGradient(viewSize /2.0f, viewSize/2.0f, Color.TRANSPARENT, Color.GREEN);

//mPaintSector设置颜色渐变渲染器

mPaintSector.setShader(shader);

}

//设置循环的方向

public void setDirection(int d){

if(d != CLOCK_WISE && d != ANSI_CLOCK_WISE){

throw new IllegalStateException("only contonst CLOCK_WISE ANSI_CLOCK_WISE");

}

this.direction = d;

}

//线程开启

public void start(){

scanThread = new ScanThread(this);

scanThread.setName("radar");

isRunning = true;

isStart = true;

scanThread.start();

}

//线程结束

public void stop(){

if(isStart){

isStart = false;

isRunning = false;

}

}

class ScanThread extends Thread{

private View view;

public ScanThread(View view) {

super();

this.view = view;

}

@Override

public void run() {

while(isRunning){

if(isStart){

start += 1;

view.post(new Runnable() {

@Override

public void run() {

//创建一个矩阵

matrix = new Matrix();

//矩阵设置旋转

matrix.preRotate(start*direction, viewSize/2.0f, viewSize/2.0f);

//重画

view.invalidate();

}

});

try {

Thread.sleep(5);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

}

public OnPointUpdateListener mListener;

//更新point的接口

public interface OnPointUpdateListener{

public void OnUpdate(Canvas canvas,Paint paintPoint,float cx,float cy,float radius);

}

public void setOnPointUpdateListener(OnPointUpdateListener listener){

this.mListener = listener;

}

}

//MainActivity中的代码

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ScanRadar radar = (ScanRadar) findViewById(R.id.scan_radar);

//随机获得一组坐标

final int[] point_x = getRandomArray(50, 10);

final int[] point_y = getRandomArray(60, 10);

radar.setOnPointUpdateListener(new OnPointUpdateListener() {

@Override

public void OnUpdate(Canvas canvas, Paint paintPoint, float cx, float cy,

float radius) {

for (int i = 0; i < point_y.length; i++) {

canvas.drawCircle(cx+point_x[i], cy+point_y[i], 5, paintPoint);

}

}

});

radar.start();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值