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

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

一、效果图

二、实现思路

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>

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

(0)

相关推荐

  • Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)

    不知不觉这个春节也已经过完了,遗憾家里没网,没能及时给大家送上祝福,今天回到深圳,明天就要上班了,小伙伴们是不是和我一样呢?今天讲的是一个大家都见过的动画,雷达搜索好友嘛,原理也十分的简单,你看完我的分析,也会觉得很简单了,国际惯例,无图无真相,我们先看看效果图,对了,真 测试机送人了,所讲这段时间应该一直用模拟器显示吧! 仿微信雷达扫描,仿安卓微信.云播雷达扫描动画效果点击中间的黑色圆圈开始扫描动画,再次点击复位,需要这种效果的朋友可以自己下载看一下. 效果图如下所示: 这个界面相信大家都认识

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

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

  • Android自定义ViewGroup实现绚丽的仿支付宝咻一咻雷达脉冲效果

    去年春节的时候支付宝推行的集福娃活动着实火的不能再火了,更给力的是春晚又可以全民参与咻一咻集福娃活动,集齐五福就可平分亿元大红包,只可惜没有敬业福--那时候在家没事写了个咻一咻插件,只要到了咻一咻的时间点插件就可以自动的点击咻一咻来咻红包,当时只是纯粹练习这部分技术代码没有公开,后续计划写篇关于插件这方面的文章,扯远了(*^__^*) --我们知道在支付宝的咻一咻页面有个雷达扩散的动画效果,当时感觉动画效果非常棒,于是私下尝试着实现了类似的效果,后来在github发现有大神也写有类似效果,于是读

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

    1.概述 最近一直到在带实习生,因为人比较多,所以很长一段时间没有更新博客了,今天更新一篇雷达扫描附近好友效果,以后尽量每周更新一篇,先看一下效果: 2.实现 1.效果分析 效果分为两个部分,一个是上半部分的自定义RadarView,还有就是下半部分的ViewPager,至于怎么做到缩放和背景虚化的效果大家可以去看看LazyViewPager这里不详细介绍,这里主要实现扫描效果部分. 2.扫描效果实现 2.1自定义RadarView在onDraw()方法中画六个圆圈,至于圆圈的半径是多少我们需要

  • Android动画之雷达扫描效果

    我们首先看一下效果图,有个整体的印象 好了,为了便于理解,这里就按照动画所见内容依次展开来说 准备 这里决定采用canvas(画布)和paint(画笔)实现了这个简单动画控件. 由图片可以看到有两条交叉的十字线.几个圆圈和一些白点,那么首先定义一下所需的画笔,画布及一些数据 setBackgroundColor(Color.TRANSPARENT); //宽度=5,抗锯齿,描边效果的白色画笔 mPaintLine = new Paint(); mPaintLine.setStrokeWidth(

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

    本文实例为大家分享了Android雷达扫描效果的具体代码,供大家参考,具体内容如下 效果图 知识点提要 Shader 矩阵matrix 属性动画 ShaderView3 package com.example.apple.shaderdemo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.

  • Android仿支付宝上芝麻信用分雷达图

    一.首先看下支付宝上芝麻信用分的效果图: 二.思路 1.确定雷达图中心点坐标 2.绘制多边形及连接线 3.根据维度值绘制覆盖区域 4.绘制分数 5.绘制每个维度的标题文字和图标 三.实现 获取布局的中心坐标 在onSizeChanged(int w, int h, int oldw, int oldh)方法里面,根据View的长宽,计算出雷达图的半径(这里取布局宽高最小值的四分之一,可以自定义),获取整个布局的中心坐标. public class CreditScoreView extends

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

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

  • Android雷达扫描动态界面制作

    先看看效果图: 源码: package com.zihao.radar; import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; import com.zihao.radar.view.RadarView; public class MainActivity extends Activity { private Rad

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

    如何制作出类似雷达扫描的效果,具体方法如下 一.效果图 二.实现思路 1.自定义控件RadarView用来画雷达的效果图,可以自定义属性包括 backgroundColor:背景颜色 circleNum:圆的数量 startColor:开始颜色 endColor:结束颜色 lineColor:线的颜色 2.通过Handler循环发送消息到MessageQueue中,将mRotate加3,使Matrix旋转mRotate,重绘雷达扫描的圆. 3.通过梯度渐变扫描渲染器SweepGradient,在

  • Android自定义控件实现滑动开关效果

    自定义开关控件 Android自定义控件一般有三种方式 1.继承Android固有的控件,在Android原生控件的基础上,进行添加功能和逻辑. 2.继承ViewGroup,这类自定义控件是可以往自己的布局里面添加其他的子控件的. 3.继承View,这类自定义控件没有跟原生的控件有太多的相似的地方,也不需要在自己的肚子里添加其他的子控件. ToggleView自定义开关控件表征上没有跟Android原生的控件有什么相似的地方,而且在滑动的效果上也没有沿袭Android原生的地方,所以我们的自定义

  • Android自定义控件实现望远镜效果

    Android自定义控件今天要讲到的就是望远镜效果,那么什么是望远镜效果,我们不妨看看下方的动图,看完后,相信大家就有一定的认识了. 1.着色器 对于这种效果来说,其实实现起来挺简单的,但我们将会用到在三维软件中的着色器Shader,它是用来给空白图形上色的.用过PS的人,相信大家都知道里面有一个印章工具,印章的样式可以是图像,颜色,渐变色等.在Android里面,Shader的效果其实与他类似. public Shader setShader(Shader shader) 上面是Shader的

  • 基于Android自定义控件实现刮刮乐效果

    只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧, 其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主activity_main 上代码!! 主activity: package com.guaguale; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; imp

  • Android自定义控件实现方向盘效果

    在很多开发中,为了界面更加的友好,在自定义View的基础上,开发者会开发出各种各样的自定义控件来满足实际开发需要,其中有一种"方向盘"的控件在实际开发中非常常见,便于用户进行一些实际性的方向控制. 在复习参考了许多自定义控件的基础上,我实现了一个最最基本的方向盘空间,并且可以根据方向做出相应的反应.话不多说,先看看效果. 做的有点丑,大家可以看看实际原理,后期再优化具体"方向盘". 空间下面的几行字是我为了确定方向所写的一些参数,基本思想就是在方向盘的中心确定一个坐

  • 基于Android实现ListView圆角效果

    本文演示如何在Android中实现ListView圆角效果. 无论是网站,还是APP,人们都爱看一些新颖的视图效果.直角看多了,就想看看圆角,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,特别是在iphone中几乎随处可见圆角设计,现在也开始出现很多圆角名片了. 现在就给大家实现一个圆角的ListView效果. 圆角的设计,我们并不追求到处都用,无处不用,android中有少数界面用直角确实容易显得锋利,和周边界面太过对比而显得不协调,比如大栏目列表,设置等等,而采用圆角实现,则会活

  • Android自定义控件实现时钟效果

    在学习安卓群英传自定义控件章节的时候,有一个例子是绘制时钟,在实现了书上的例子后就想看这个时钟能不能动起来. 这里选择延迟一秒发送消息重绘view来实现的动画,对外提供了开启时钟,关闭时钟的方法,当activity执行onResume方法的时候,执行startClock()方法,当移除view或activity执行onStop方法的时候可以执行stopClock()方法. 首先根据view的宽高来确定圆心的位置,并画出一个圆.再通过view高度的一半减去圆的半径,确定刻度的起始位置,选择刻度的长

  • Android自定义控件EditText使用详解

    本文实例为大家分享了Android自定义控件EditText的具体代码,供大家参考,具体内容如下 自定义控件分三种: 1. 自绘控件 2. 组合控件 3. 继承控件 代码已上传到 github 以后的自定义控件就都放这个仓库 需求 这里由于项目的需要实现一个自定义EditText,主要实现的为两点,一个是工具图标toolIcon,例如点击清除EditText内容.一个为EditText左边的提示图标hintIcon, 例如输入账号密码时前面的图标. 为了让这个控件的拓展性更高,设置了两个点击事件

  • Android自定义控件打造绚丽平行空间引导页

    本文实例为大家分享了Android自定义控件打造平行空间引导页的具体代码,供大家参考,具体内容如下 先上图,动图太大传不上来,在项目中有动图 点击查看动图 首先解释下工程的主要部分. 首先谷歌的百分比布局做了部分修改,因为我设置的宽高都是相对于屏幕的宽度,而谷歌的百分比布局不能实现,只需要修改一部分代码就可以实现.下面贴出修改的部分代码 public static class PercentLayoutInfo { private enum BASEMODE { BASE_WIDTH, BASE

  • 实例讲解Android自定义控件

    小编在此之前给大家介绍过关于Android自定义控件的用法等,需要的可以参考下: Android开发之自定义控件用法详解 详解Android自定义控件属性 可以看到QQ上的ToolBar其实就是一个自定义的view,可以看到不同的界面就是简单地修改了文字而已,在第二张与第三张尤其的明显,我们就仿QQ的这个Toolbar设置一个自定义控件 在开始之前,首先了解一下官方是如何实现一个控件的,比如说一个Linearlayout 它不是有layout_width和layout_height这两个属性吗?

随机推荐