Android自定义控件入门实践之雷达扫描控件

简介: 以前因为工作的关系,对于自定义控件用的少之又少,无非就是把几个控件放置到ViewGroup内部,然后提供开放方法,就成了一个所谓的自定义控件,但是这种小伎俩太简单,面试的时候这点东西根本Hold不住场,所以工作之余还是得把这块补补,也好加深一下对控件的理解。

以前因为工作的关系,对于自定义控件用的少之又少,无非就是把几个控件放置到ViewGroup内部,然后提供开放方法,就成了一个所谓的自定义控件,但是这种小伎俩太简单,面试的时候这点东西根本Hold不住场,所以工作之余还是得把这块补补,也好加深一下对控件的理解。

好,啰嗦了挺多的,我们先看一下实现的效果:


只是截取了一部分运行时图,这个控件只是重写了onDraw方法,其它一一保留给View,简单说一下这个的实现方式:

使用一只画笔用来画等距的四个圆,使用另外一只画笔画一个标准的角度渐变图。

Android提供了标准的渐变图,同样在PhotoShop中我们一样可以找到这些渐变图,这样一来,我们就可以根据UI设计师设计的套路来做同样的效果了:


线性渐变图


径向渐变图


菱形渐变图


角度渐变图


对称渐变图

好了,我们将这些基本的图绘制出来之后,它还是个静态的,我们需要将它动起来,那怎么使它动起来呢,对,我们需要线程来驱动它进行重绘,需要注意的是,线程一定要出口。

开启线程有两种方式,一种是传统的开线程的方式,使用Thread。另一种则使用向主线程消息队列中发送消息来驱动。我们使用第二种:hander.postRunnable。

来贴一下整体的代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;


/**
 * 雷达显示控件
 * Created by Sahadev on 2015/12/29.
 * 邮箱:sahadev@foxmail.com
 */
public class RadarView extends View implements Runnable {
    private boolean threadFlag = true;
    private int rotate = 0;
    //用于画圆的画笔
    private Paint circlePaint;
    //用于画扫描图像
    private Paint shaderPaint;
    //获得用于画圆的坐标位置以及半径
    int x, y;
    //设置扫描图像的坐标矩阵
    Matrix matrix = new Matrix();
    //用于绘制扫描图像
    Shader mShader;

    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);

        //为了避免在onDraw中重复创建对象,所以将一些初始化工作放入构造方法中来做

        circlePaint = new Paint();
        circlePaint.setColor(Color.WHITE);
        //设置画笔的宽度
        circlePaint.setStrokeWidth(1);
        //设置抗锯齿模式
        circlePaint.setAntiAlias(true);
        circlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        //设置画笔风格
        circlePaint.setStyle(Paint.Style.STROKE);

        shaderPaint = new Paint();
        shaderPaint.setAntiAlias(true);
        shaderPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
        //设置画笔风格为填充模式
        shaderPaint.setStyle(Paint.Style.FILL);

        postDelayed(this, 100);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //计算圆的坐标值及半径
        y = getMeasuredHeight() / 2;
        x = getMeasuredWidth() / 2;

        //为矩阵设置旋转坐标
        matrix.setRotate(rotate, x, y);

        //为了避免重复创建对象,则使用这种方式
        if (mShader == null)
            mShader = new SweepGradient(x, y, Color.TRANSPARENT, Color.BLUE);

        mShader.setLocalMatrix(matrix);
        shaderPaint.setShader(mShader);

        //画一个扫描图像
        canvas.drawCircle(x, y, x, shaderPaint);

        //画四个等距圆
        canvas.drawCircle(x, y, x, circlePaint);
        canvas.drawCircle(x, y, x / 2, circlePaint);
        canvas.drawCircle(x, y, x / 4 * 3, circlePaint);
        canvas.drawCircle(x, y, x / 4, circlePaint);
    }

    @Override
    public void run() {
        if (threadFlag) {
            rotate++;
            postInvalidate();
            //如果到了360度,则重新开始
            rotate = rotate == 360 ? 0 : rotate;
            //一秒延迟这个任务
            postDelayed(this, 1);
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        //停止循环
        threadFlag = false;
    }

}

好,这样运行起来就是我们图例所显示的样子,最后看一下内存使用以及CPU使用情况:


都不是很多,这只是最基本的,我们还可以将它进一步的优化。


有什么疑问欢迎留言讨论。

目录
相关文章
|
2月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
102 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
6月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
391 2
|
6月前
|
Android开发
Android控件样式的抽取(小提及快捷方式)
在Android开发中,若多个控件样式重复,可抽取公共部分以简化代码。例如对EditText提取样式,通过编辑`styles.xml`实现复用。为提高效率,Android Studio提供自动提取Style功能:右键点击控件样式选项,选择“Style...”,勾选需要提取的属性后确认,即可快速生成样式代码,显著提升开发便利性。
195 2
|
11月前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
147 2
|
12月前
|
XML 数据库 Android开发
探索Android开发:从入门到精通的旅程
在这篇文章中,我们将一起踏上一段激动人心的旅程,通过深入浅出的方式,解锁Android开发的秘密。无论你是编程新手还是有经验的开发者,本文都将为你提供宝贵的知识和技能,帮助你构建出色的Android应用。我们将从基础概念开始,逐步深入到高级技巧和最佳实践,最终实现从初学者到专家的转变。让我们开始吧!
257 3
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
XML IDE Java
安卓应用开发入门:从零开始的旅程
【10月更文挑战第23天】本文将带领读者开启一段安卓应用开发的奇妙之旅。我们将从最基础的概念讲起,逐步深入到开发实践,最后通过一个简易的代码示例,展示如何将理论知识转化为实际的应用。无论你是编程新手,还是希望扩展技能的软件工程师,这篇文章都将为你提供有价值的指导和启发。
158 0

热门文章

最新文章