当前位置: 移动技术网 > IT编程>移动开发>Android > 基于Android自定义控件实现雷达效果

基于Android自定义控件实现雷达效果

2019年07月24日  | 移动技术网IT编程  | 我要评论

疯博乐,郑州天气预报一周,王音祺

如何制作出类似雷达扫描的效果,具体方法如下

一、效果图

这里写图片描述

二、实现思路

1、自定义控件radarview用来画雷达的效果图,可以自定义属性包括

backgroundcolor:背景颜色
circlenum:圆的数量
startcolor:开始颜色
endcolor:结束颜色
linecolor:线的颜色

2、通过handler循环发送消息到messagequeue中,将mrotate加3,使matrix旋转mrotate,重绘雷达扫描的圆。

3、通过梯度渐变扫描渲染器sweepgradient,在绘制圆的过程中,将颜色从startcolor变为endcolor。

三、实例代码

public class radarview extends view {
 private final string tag = "radarview";

 private static final int msg_what = 1;

 private static final int delay_time = 20;

 //设置默认宽高,雷达一般都是圆形,所以我们下面取宽高会取math.min(宽,高)
 private final int default_width = 200;

 private final int default_height = 200;
 //雷达的半径
 private int mradarradius;
 //雷达画笔
 private paint mradarpaint;
 //雷达底色画笔
 private paint mradarbg;
 //雷达圆圈的个数,默认4个
 private int mcirclenum = 4;
 //雷达线条的颜色,默认为白色
 private int mcirclecolor = color.white;
 //雷达圆圈背景色
 private int mradarbgcolor = color.black;
 //paintshader
 private shader mradarshader;

 //雷达扫描时候的起始和终止颜色
 private int mstartcolor = 0x0000ff00;

 private int mendcolor = 0xaa00ff00;


 private matrix mmatrix;

 //旋转的角度
 private int mrotate = 0;

 private handler mhandler = new handler() {
  @override
  public void handlemessage(message msg) {
   super.handlemessage(msg);

   mrotate += 3;
   postinvalidate();

   mmatrix.reset();
   mmatrix.prerotate(mrotate, 0, 0);
   //延时delay_time后再发送消息
   mhandler.sendemptymessagedelayed(msg_what, delay_time);
  }
 };

 public radarview(context context) {
  this(context, null);
 }

 public radarview(context context, attributeset attrs) {
  this(context, attrs, 0);
 }

 public radarview(context context, attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  init(context, attrs);

  //设置抗锯齿
  mradarbg = new paint(paint.anti_alias_flag);
  //画笔颜色
  mradarbg.setcolor(mradarbgcolor);
  //画实心圆
  mradarbg.setstyle(paint.style.fill);

  //设置抗锯齿
  mradarpaint = new paint(paint.anti_alias_flag);
  //画笔颜色
  mradarpaint.setcolor(mcirclecolor);
  //设置空心的画笔,只画圆边
  mradarpaint.setstyle(paint.style.stroke);
  //画笔宽度
  mradarpaint.setstrokewidth(2);
  //使用梯度渐变渲染器,
  mradarshader = new sweepgradient(0, 0, mstartcolor, mendcolor);

  mmatrix = new matrix();
 }


 //初始化,拓展可设置参数供布局使用
 private void init(context context, attributeset attrs) {
  if (attrs != null) {
   typedarray ta = context.obtainstyledattributes(attrs, r.styleable.radarview);
   mstartcolor = ta.getcolor(r.styleable.radarview_startcolor, mstartcolor);
   mendcolor = ta.getcolor(r.styleable.radarview_endcolor, mendcolor);
   mradarbgcolor = ta.getcolor(r.styleable.radarview_backgroundcolor, mradarbgcolor);
   mcirclecolor = ta.getcolor(r.styleable.radarview_linecolor, mcirclecolor);
   mcirclenum = ta.getinteger(r.styleable.radarview_circlenum, mcirclenum);
   ta.recycle();
  }
 }


 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
  super.onsizechanged(w, h, oldw, oldh);
  //雷达的半径为宽的一半或高的一半的最小值
  mradarradius = math.min(w / 2, h / 2);
 }

 @override
 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
  super.onmeasure(widthmeasurespec, heightmeasurespec);
  //获取宽度
  int width = measuresize(1, default_width, widthmeasurespec);
  //获取高度
  int height = measuresize(0, default_height, heightmeasurespec);

  //取最大的 宽|高
  int measuresize = math.max(width, height);
  setmeasureddimension(measuresize, measuresize);
 }


 /**
  * 测绘measure
  *
  * @param spectype 1为宽, 其他为高
  * @param contentsize 默认值
  */
 private int measuresize(int spectype, int contentsize, int measurespec) {
  int result;
  //获取测量的模式和size
  int specmode = measurespec.getmode(measurespec);
  int specsize = measurespec.getsize(measurespec);

  if (specmode == measurespec.exactly) {
   result = math.max(contentsize, specsize);
  } else {
   result = contentsize;

   if (spectype == 1) {
    // 根据传入方式计算宽
    result += (getpaddingleft() + getpaddingright());
   } else {
    // 根据传入方式计算高
    result += (getpaddingtop() + getpaddingbottom());
   }
  }

  return result;

 }


 @override
 protected void ondraw(canvas canvas) {
  super.ondraw(canvas);

  log.d(tag, "ondraw " + mrotate);

  mradarbg.setshader(null);

  //将画布移动到屏幕的中心点
  canvas.translate(mradarradius, mradarradius);
  //绘制底色,让雷达的线看起来更清晰
  canvas.drawcircle(0, 0, mradarradius, mradarbg);
  //画圆圈
  for (int i = 1; i <= mcirclenum; i++) {
   canvas.drawcircle(0, 0, (float) (i * 1.0 / mcirclenum * mradarradius), mradarpaint);
  }
  //绘制雷达基线 x轴
  canvas.drawline(-mradarradius, 0, mradarradius, 0, mradarpaint);
  //绘制雷达基线 y轴
  canvas.drawline(0, mradarradius, 0, -mradarradius, mradarpaint);
  //设置颜色渐变从透明到不透明
  mradarbg.setshader(mradarshader);
  //设置矩阵
  canvas.concat(mmatrix);
  canvas.drawcircle(0, 0, mradarradius, mradarbg);
 }


 public void startscan() {
  mhandler.removemessages(msg_what);
  mhandler.sendemptymessage(msg_what);
 }

 public void stopscan() {
  mhandler.removemessages(msg_what);
 }
}

布局文件:

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:app="http://schemas.android.com/apk/res-auto"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 >
 <com.android.demo.ui.shader.radarview
  android:id="@+id/radarview"
  android:layout_width="300dp"
  android:layout_height="300dp"
  android:layout_centerinparent="true"
  app:backgroundcolor="#000000"
  app:circlenum="4"
  app:endcolor="#aaff0000"
  app:linecolor="#00ff00"
  app:startcolor="#aa0000ff"/>

 <button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignparentleft="true"
  android:layout_alignparentbottom="true"
  android:onclick="start"
  android:text="开始" />

 <button
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignparentright="true"
  android:layout_alignparentbottom="true"
  android:onclick="stop"
  android:text="停止" />
</relativelayout>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网