我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android动画之雷达扫描效果

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android动画之雷达扫描效果

我们首先看一下效果图,有个整体的印象

好了,为了便于理解,这里就按照动画所见内容依次展开来说

准备

这里决定采用canvas(画布)和paint(画笔)实现了这个简单动画控件。

由图片可以看到有两条交叉的十字线、几个圆圈和一些白点,那么首先定义一下所需的画笔,画布及一些数据


  setBackgroundColor(Color.TRANSPARENT);
  //宽度=5,抗锯齿,描边效果的白色画笔
  mPaintLine = new Paint();
  mPaintLine.setStrokeWidth(5);
  mPaintLine.setAntiAlias(true);
  mPaintLine.setStyle(Style.STROKE);
  mPaintLine.setColor(Color.WHITE);
  //宽度=5,抗锯齿,描边效果的浅绿色画笔
  mPaintCircle = new Paint();
  mPaintCircle.setStrokeWidth(5);
  mPaintCircle.setAntiAlias(true);
  mPaintCircle.setStyle(Style.FILL);
  mPaintCircle.setColor(0x99000000);
  //暗绿色的画笔
  mPaintSector = new Paint();
  mPaintSector.setColor(0x9D00ff00);
  mPaintSector.setAntiAlias(true);
  //定义一个暗绿色的梯度渲染
  mShader = new SweepGradient(viewSize / 2, viewSize / 2,
 Color.TRANSPARENT, Color.GREEN);
  mPaintSector.setShader(mShader);
  //白色实心画笔
  mPaintPoint=new Paint();
  mPaintPoint.setColor(Color.WHITE);
  mPaintPoint.setStyle(Style.FILL);
  //随机生成一些数组点,模拟雷达扫描结果
  point_x = UtilTools.Getrandomarray(15, 300);
  point_y = UtilTools.Getrandomarray(15, 300);

这里说一下这个SweepGradient

SweepGradient的构造函数:


public SweepGradient(float cx, float cy, int[] colors, float[] positions)



public SweepGradient(float cx, float cy, int color0, int color1)

其中cx,cy 指定圆心, color1,color0 或 colors 指定渐变的颜色 ,对于使用多于两种颜色时,还可以通过positions 指定每种颜色的相对位置,positions 设为NULL时表示颜色均匀分布。

绘制基本图形


  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintCircle);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 255, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 125, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintLine);
  //绘制两条十字线
  canvas.drawLine(viewSize / 2, 0, viewSize / 2, viewSize, mPaintLine);
  canvas.drawLine(0, viewSize / 2, viewSize, viewSize / 2, mPaintLine);

这样就绘制除了整个UI,接下来加上动画,就可以实现整体的效果。

动画实现

这里实现动画的时候,用到了Matrix这个东西,也就是矩阵。上学的时候,线性代数老师讲各种线性变换时,脑子里在想,这玩意是干嘛使得,现在总算是遇上了,现在看起来也是云里雾里。总的来说就是可以使用Matrix实现强大的图形动画,包括位移、旋转、缩放及透明变化等效果,matrix有着一系列的setTranslate,setRotate,setScale等方法。很方便的实现图形各种变换,主要还是需要理解各种变换。

动画实现线程


 protected class ScanThread extends Thread {
  private RadarView view;
  public ScanThread(RadarView view) {
   // TODO Auto-generated constructor stub
   this.view = view;
  }
  @Override
  public void run() {
   // TODO Auto-generated method stub
   while (threadRunning) {
    if (isstart) {
     view.post(new Runnable() {
      public void run() {
       start = start + 1;
       matrix = new Matrix();
       //设定旋转角度,制定进行转转操作的圆心
//       matrix.postRotate(start, viewSize / 2, viewSize / 2);
//       matrix.setRotate(start,viewSize/2,viewSize/2);
       matrix.preRotate(direction*start,viewSize/2,viewSize/2);
       view.invalidate();
      }
     });
     try {
      Thread.sleep(5);
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
   }
  }
 }

首先,这里在一个独立线程中不断的对start做累加,作为旋转角度。然后将其和matrix关联。这里尝试使用了matrix的三个方法,暂时没有发现区别。

动画绘制

接下来在onDraw方法中不断绘制图形即可


  //根据matrix中设定角度,不断绘制shader,呈现出一种扇形扫描效果
  canvas.concat(matrix);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintSector);

最终实现

好了,最终整体的代码如下:


public class RadarView extends FrameLayout {
 private Context mContext;
 private int viewSize = 800;
 private Paint mPaintLine;
 private Paint mPaintCircle;
 private Paint mPaintSector;
 public boolean isstart = false;
 private ScanThread mThread;
 private Paint mPaintPoint;
 //旋转效果起始角度
 private int start = 0;
 private int[] point_x;
 private int[] point_y;
 private Shader mShader;
 private Matrix matrix;
 public final static int CLOCK_WISE=1;
 public final static int ANTI_CLOCK_WISE=-1;
 @IntDef({ CLOCK_WISE, ANTI_CLOCK_WISE })
 public @interface RADAR_DIRECTION {
 }
 //默认为顺时针呢
 private final static int DEFAULT_DIERCTION=CLOCK_WISE;
 //设定雷达扫描方向
 private int direction=DEFAULT_DIERCTION;
 private boolean threadRunning = true;
 public RadarView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  mContext = context;
  initPaint();
 }
 public RadarView(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
  mContext = context;
  initPaint();
 }
 private void initPaint() {
  // TODO Auto-generated method stub
  setBackgroundColor(Color.TRANSPARENT);
  //宽度=5,抗锯齿,描边效果的白色画笔
  mPaintLine = new Paint();
  mPaintLine.setStrokeWidth(5);
  mPaintLine.setAntiAlias(true);
  mPaintLine.setStyle(Style.STROKE);
  mPaintLine.setColor(Color.WHITE);
  //宽度=5,抗锯齿,描边效果的浅绿色画笔
  mPaintCircle = new Paint();
  mPaintCircle.setStrokeWidth(5);
  mPaintCircle.setAntiAlias(true);
  mPaintCircle.setStyle(Style.FILL);
  mPaintCircle.setColor(0x99000000);
  //暗绿色的画笔
  mPaintSector = new Paint();
  mPaintSector.setColor(0x9D00ff00);
  mPaintSector.setAntiAlias(true);
  mShader = new SweepGradient(viewSize / 2, viewSize / 2, Color.TRANSPARENT, Color.GREEN);
  mPaintSector.setShader(mShader);
  //白色实心画笔
  mPaintPoint=new Paint();
  mPaintPoint.setColor(Color.WHITE);
  mPaintPoint.setStyle(Style.FILL);
  //随机生成的点,模拟雷达扫描结果
  point_x = UtilTools.Getrandomarray(15, 300);
  point_y = UtilTools.Getrandomarray(15, 300);
 }
 public void setViewSize(int size) {
  this.viewSize = size;
  setMeasuredDimension(viewSize, viewSize);
 }
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  // TODO Auto-generated method stub
  setMeasuredDimension(viewSize, viewSize);
 }
 public void start() {
  mThread = new ScanThread(this);
  mThread.setName("radar");
  mThread.start();
  threadRunning = true;
  isstart = true;
 }
 public void stop() {
  if (isstart) {
   threadRunning = false;
   isstart = false;
  }
 }
 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintCircle);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 255, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 125, mPaintLine);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintLine);
  //绘制两条十字线
  canvas.drawLine(viewSize / 2, 0, viewSize / 2, viewSize, mPaintLine);
  canvas.drawLine(0, viewSize / 2, viewSize, viewSize / 2, mPaintLine);
  //这里在雷达扫描过制定圆周度数后,将随机绘制一些白点,模拟搜索结果
  if (start > 100) {
   for (int i = 0; i < 2; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 200) {
   for (int i = 2; i < 5; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 300) {
   for (int i = 5; i < 9; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 500) {
   for (int i = 9; i < 11; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  if (start > 800) {
   for (int i = 11; i < point_x.length; i++) {
    canvas.drawCircle(viewSize / 2 + point_x[i], viewSize / 2 + point_y[i], 10, mPaintPoint);
   }
  }
  //根据matrix中设定角度,不断绘制shader,呈现出一种扇形扫描效果
  canvas.concat(matrix);
  canvas.drawCircle(viewSize / 2, viewSize / 2, 350, mPaintSector);
  super.onDraw(canvas);
 }
 public void setDirection(@RADAR_DIRECTION int direction) {
  if (direction != CLOCK_WISE && direction != ANTI_CLOCK_WISE) {
   throw new IllegalArgumentException("Use @RADAR_DIRECTION constants only!");
  }
  this.direction = direction;
 }
 protected class ScanThread extends Thread {
  private RadarView view;
  public ScanThread(RadarView view) {
   // TODO Auto-generated constructor stub
   this.view = view;
  }
  @Override
  public void run() {
   // TODO Auto-generated method stub
   while (threadRunning) {
    if (isstart) {
     view.post(new Runnable() {
      public void run() {
       start = start + 1;
       matrix = new Matrix();
       //设定旋转角度,制定进行转转操作的圆心
//       matrix.postRotate(start, viewSize / 2, viewSize / 2);
//       matrix.setRotate(start,viewSize/2,viewSize/2);
       matrix.preRotate(direction*start,viewSize/2,viewSize/2);
       view.invalidate();
      }
     });
     try {
      Thread.sleep(5);
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
   }
  }
 }
}

说明

多余的部分就不再解释,代码里已经注释的很清楚。这个RadarView的使用也是很简单,需要停止时,调用其stop方法即可。


@Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RadarView radarView = (RadarView) findViewById(R.id.radar);
  //设置雷达扫描方向
  radarView.setDirection(RadarView.ANTI_CLOCK_WISE);
  radarView.start();
 }

这里雷达ViewSize设置为800,所以在布局文件中设定大小时将不起作用,正常使用时,需根据实际需求调整viewsize大小和几个Circle的半径,从而达到更有好的UI展示效果。

总结

以上就是Android中雷达扫描效果实现的全部内容,希望本文对大家Android开发有所帮助。

您可能感兴趣的文章:Android Shader应用开发之雷达扫描效果Android仿微信雷达扫描效果的实现方法Android仿微信、QQ附近好友雷达扫描效果Android雷达扫描动态界面制作Android自定义ViewGroup实现绚丽的仿支付宝咻一咻雷达脉冲效果Android仿支付宝上芝麻信用分雷达图Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)Android编程简单实现雷达扫描效果基于Android自定义控件实现雷达效果


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android动画之雷达扫描效果

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android动画之雷达扫描效果

我们首先看一下效果图,有个整体的印象好了,为了便于理解,这里就按照动画所见内容依次展开来说 准备这里决定采用canvas(画布)和paint(画笔)实现了这个简单动画控件。 由图片可以看到有两条交叉的十字线、几个圆圈和一些白点,那么首先定义
2022-06-06

Android Shader应用开发之雷达扫描效果

本文实例为大家分享了Android雷达扫描效果的具体代码,供大家参考,具体内容如下效果图知识点提要 Shader 矩阵matrix 属性动画 ShaderView3package com.example.apple.shaderde
2023-05-30

iOS实现雷达扫描效果

本文实例为大家分享了iOS实现雷达扫描的具体代码,供大家参考,具体内容如下#import @interface LTIndicatiorView : UIView @property(nonatomic,str
2022-05-27

Android编程简单实现雷达扫描效果

本文实例讲述了Android编程简单实现雷达扫描效果。分享给大家供大家参考,具体如下: 在eoe看到有一篇关于雷达扫描的文章,然后看了下,很简单,但是觉得还有很多可以优化的地方,下面贴出来package com.example.wave;
2022-06-06

利用Qt绘制雷达扫描效果

这篇文章主要为大家详细介绍了如何利用Qt绘制简单的雷达扫描效果,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
2023-05-14

iOS自定义雷达扫描扩散动画

本文实例为大家分享了iOS实现雷达扫描扩散动画的具体代码,供大家参考,具体内容如下 自己自定义了 一个雷达扫描/扩散效果的View。 扫描View 效果如下:扩散View 效果如下:自定义的代码如下: 1. RadarView.h#impo
2022-05-27

Android雷达扫描动态界面制作

先看看效果图:源码:package com.zihao.radar; import android.app.Activity; import android.os.Bundle; import android.view.Window;
2022-06-06

Android仿微信、QQ附近好友雷达扫描效果

1.概述最近一直到在带实习生,因为人比较多,所以很长一段时间没有更新博客了,今天更新一篇雷达扫描附近好友效果,以后尽量每周更新一篇,先看一下效果: 2.实现  1、效果分析 效果分为两个部分,一个是上半部分的自定义RadarView,还有就
2022-06-06

Android仿微信雷达扫描效果的实现方法

本文主要给大家介绍的是关于Android实现微信雷达扫描效果的相关内容,分享出来供大家参考学习,下面来看看详细的介绍:废话不多说 先上图(用AS录制的 转换工具不是很好 所以看得效果不是很好)效果图示例代码Activity 代码public
2023-05-31

怎么用Qt绘制雷达扫描效果

本文小编为大家详细介绍“怎么用Qt绘制雷达扫描效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Qt绘制雷达扫描效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。scan.h的代码如下#ifndef SC
2023-07-05

CSS3如何实现雷达圈动画效果

这篇文章主要介绍了CSS3如何实现雷达圈动画效果的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇CSS3如何实现雷达圈动画效果文章都会有所收获,下面我们一起来看看吧。效果:html代码:2023-07-04

Android基础知识之frame动画效果

上一篇我们说了Android中的tween动画,这一篇我们说说frame动画,frame动画主要是实现了一种类似于gif动画的效果,就是多张图按预先设定好的时间依次连续显示。 新建一个android项目,名字叫做frameTest,在re
2022-06-06

Android基础知识之tween动画效果

Android中一共提供了两种动画,其一便是tween动画,tween动画通过对view的内容进行一系列的图像变换(包括平移,缩放,旋转,改变透明度)来实现动画效果,动画效果的定义可以使用xml,也可以使用编码来实现。 下面我们逐一查看tw
2022-06-06

我的Android开发之旅(四):Android三种动画效果的浅入之帧动画

我的Android开发之旅(四):Android三种动画效果的浅入之帧动画1. 前言2. 帧动画3. 如何使用3.1 AnimationDrawable3.2 Xml实现3.3 Java实现4. 淡入淡出动画5. 尾声 1. 前言 ​ A
2022-06-06

Android动画效果之自定义ViewGroup添加布局动画(五)

前言:前面几篇文章介绍了补间动画、逐帧动画、属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画。本文将通过对自定义图片选择控件设置动画为例来学习布
2022-06-06

我的Android开发之旅(二):Android三种动画效果的浅入之View动画

我的Android开发之旅(二):Android三种动画效果的浅入之View动画前言View动画Animation类1. 平移动画2. 缩放动画3. 旋转动画4. 透明动画AnimationSet 动画集合自定义View动画补充 前言 在A
2022-06-06

Android Animation实战之一个APP的ListView的动画效果

熟悉了基础动画的实现后,便可以试着去实现常见APP中出现过的那些精美的动画。今天我主要给大家引入一个APP的ListView的动画效果: 当展示ListView时,Listview的每一个列表项都按照规定的动画显示出来。 说起来比较抽象,先
2022-06-06

Android动画之3D翻转效果实现函数分析

Android中的翻转动画效果的实现,首先看一下运行效果如上图所示. Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和 Transformation。
2022-06-06

Android编程之界面跳动提示动画效果实现方法

本文实例讲述了Android编程之界面跳动提示动画效果实现方法。分享给大家供大家参考,具体如下: 上一个效果图:先上布局:2022-06-06

Android开发之图形图像与动画(三)Animation效果的XML实现

使用XML来定义Tween Animation 动画的XML文件在工程中res/anim目录,这个文件必须包含一个根元素,可以使 插值元素或者是把上面的元素都放入
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录