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使用情况:


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


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

目录
相关文章
|
25天前
|
调度 数据库 Android开发
构建高效Android应用:Kotlin协程的实践与优化
在Android开发领域,Kotlin以其简洁的语法和平台友好性成为了开发的首选语言。其中,Kotlin协程作为处理异步任务的强大工具,它通过提供轻量级的线程管理机制,使得开发者能够在不阻塞主线程的情况下执行后台任务,从而提升应用性能和用户体验。本文将深入探讨Kotlin协程的核心概念,并通过实例演示如何在实际的Android应用中有效地使用协程进行网络请求、数据库操作以及UI的流畅更新。同时,我们还将讨论协程的调试技巧和常见问题的解决方法,以帮助开发者避免常见的陷阱,构建更加健壮和高效的Android应用。
33 4
|
27天前
|
移动开发 Java Android开发
构建高效Android应用:Kotlin协程的实践之路
【2月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验一直是开发者追求的目标。随着Kotlin语言的流行,其异步编程解决方案——协程(Coroutines),为Android应用带来了革命性的并发处理能力。本文将深入探讨Kotlin协程的核心概念、设计原理以及在Android应用中的实际应用案例,旨在帮助开发者掌握这一强大的工具,从而提升应用的性能和响应能力。
|
29天前
|
移动开发 调度 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【2月更文挑战第30天】 在移动开发领域,尤其是针对Android平台,性能优化和应用流畅度始终是开发者关注的重点。近年来,Kotlin语言凭借其简洁性和功能性成为Android开发的热门选择。其中,Kotlin协程作为一种轻量级的线程管理解决方案,为异步编程提供了强大支持,使得编写非阻塞性代码变得更加容易。本文将深入分析Kotlin协程的核心优势,并通过实际案例展示如何有效利用协程提升Android应用的性能和响应速度。
|
1月前
|
数据库 Android开发 开发者
构建高性能微服务架构:从理论到实践构建高效Android应用:探究Kotlin协程的优势
【2月更文挑战第16天】 在当今快速迭代和竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性和独立部署能力而受到企业的青睐。本文将深入探讨如何构建一个高性能的微服务系统,涵盖从理论基础到具体实现的各个方面。我们将重点讨论服务拆分策略、通信机制、数据一致性以及性能优化等关键主题,为读者提供一个清晰、实用的指南,以便在复杂多变的业务环境中构建和维护健壮的微服务体系结构。 【2月更文挑战第16天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着技术的不断进步,Kotlin作为一种现代编程语言,在Android开发中被广泛采用,尤其是其协程特性为异步编程带来了革命性的改进。本文旨在深入
239 5
|
17天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践与优化
在响应式编程范式日益盛行的今天,Kotlin协程作为一种轻量级的线程管理解决方案,为Android开发带来了性能和效率的双重提升。本文旨在探讨Kotlin协程的核心概念、实践方法及其在Android应用中的优化策略,帮助开发者构建更加流畅和高效的应用程序。通过深入分析协程的原理与应用场景,结合实际案例,本文将指导读者如何优雅地解决异步任务处理,避免阻塞UI线程,从而优化用户体验。
|
11天前
|
移动开发 API Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【4月更文挑战第7天】 在移动开发领域,性能优化和应用响应性的提升一直是开发者追求的目标。近年来,Kotlin语言因其简洁性和功能性在Android社区中受到青睐,特别是其对协程(Coroutines)的支持,为编写异步代码和处理并发任务提供了一种更加优雅的解决方案。本文将探讨Kotlin协程在Android开发中的应用,揭示其在提高应用性能和简化代码结构方面的潜在优势,并展示如何在实际项目中实现和优化协程。
|
28天前
|
移动开发 安全 Android开发
构建高效Android应用:探究Kotlin协程的优势与实践
【2月更文挑战第30天】 在移动开发领域,性能优化和应用流畅度始终是开发者追求的核心目标。特别是对于Android平台,由于设备多样性和系统资源限制,如何提升应用的响应速度和处理效率成为关键挑战。近年来,Kotlin语言因其简洁、安全且易于阅读的特性而广受欢迎。其中,Kotlin协程作为一种轻量级的线程管理方案,提供了异步编程的强大能力,使得编写非阻塞性代码变得简单高效。本文将深入探讨Kotlin协程在Android开发中的应用优势,并通过实例演示如何在实际项目中有效利用协程来改善应用性能。
|
1月前
|
Android开发
[Android]RadioButton控件
[Android]RadioButton控件
12 0
|
1月前
|
测试技术 API 调度
【Android 从入门到出门】第七章:开始使用WorkManager
【Android 从入门到出门】第七章:开始使用WorkManager
19 3
【Android 从入门到出门】第七章:开始使用WorkManager
|
1月前
|
存储 Android开发 C++
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
【Android 从入门到出门】第五章:使用DataStore存储数据和测试
30 3