基于Android自定义控件实现雷达效果
程序员文章站
2024-02-06 20:13:28
如何制作出类似雷达扫描的效果,具体方法如下
一、效果图
二、实现思路
1、自定义控件radarview用来画雷达的效果图,可以自定义属性包括
bac...
如何制作出类似雷达扫描的效果,具体方法如下
一、效果图
二、实现思路
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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
基于Android自定义控件实现雷达效果
-
Android编程基于自定义view实现公章效果示例【附源码下载】
-
Android自定义控件:图形报表的实现(折线图、曲线图、动态曲线图)(View与SurfaceView分别实现图表控件)
-
android 中win10 使用uwp控件实现进度条Marquez效果
-
Android基于google Zxing实现各类二维码扫描效果
-
Android编程实现GridView控件点击图片变暗效果的方法
-
Android自定义View实现叶子飘动旋转效果(四)
-
Android自定义控件实现带文字提示的SeekBar
-
Android自定义控件实现通用验证码输入框(二)
-
Android自定义控件仿ios下拉回弹效果