Android自定义View之酷炫圆环(二)

yizhihongxing

我来为你详细讲解Android自定义View之酷炫圆环(二)的完整攻略。

1、前言

本文是 Android 自定义 View 系列的第二篇,主要讲解如何实现一个非常酷炫的圆环控件,使用者可以通过设置一些属性来自定义样式,比如说环的宽度、颜色、进度等。代码中会用到一些自定义属性以及一些 Canvas 的绘图技巧,用以实现一个非常酷炫的控件。

2、实现一个简单的圆环

首先,我们先来看如何在 Android 中绘制一个简单的圆环,代码如下:

public class SimpleCircleView extends View {
    private Paint mPaint;

    public SimpleCircleView(Context context) {
        this(context, null);
    }

    public SimpleCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SimpleCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(10f);
        mPaint.setColor(Color.RED);
    }

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

        float radius = (Math.min(getWidth(), getHeight()) - getPaddingLeft() - getPaddingRight()) / 2;

        canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, mPaint);
    }
}

其中,我们在构造方法中初始化画笔,并设置它的一些属性,比如说画笔的样式、抗锯齿、宽度和颜色等。在 onDraw 方法中,则是通过 Canvas 绘制一个圆,圆的半径取决于 View 的宽高以及 Padding。

3、实现一个带进度的圆环

接下来,我们要实现的是一个带进度的圆环,具体思路如下:

  1. 通过自定义属性设置圆环的颜色、宽度、进度颜色等;
  2. 添加一个 setProgress 方法,当调用该方法时,我们就更新进度并重新绘制整个圆环。

下面是详细的实现代码:

public class ProgressCircleView extends View {
    private int mCircleColor;
    private int mCircleWidth;
    private int mProgressColor;
    private int mProgress;
    private boolean mShowProgressText;

    private Paint mCirclePaint;
    private Paint mProgressPaint;
    private Paint mTextPaint;

    public ProgressCircleView(Context context) {
        this(context, null);
    }

    public ProgressCircleView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ProgressCircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ProgressCircleView);

        mCircleColor = a.getColor(R.styleable.ProgressCircleView_circleColor, Color.RED);
        mCircleWidth = a.getDimensionPixelSize(R.styleable.ProgressCircleView_circleWidth, 10);
        mProgressColor = a.getColor(R.styleable.ProgressCircleView_progressColor, Color.BLUE);
        mProgress = a.getInt(R.styleable.ProgressCircleView_progress, 0);
        mShowProgressText = a.getBoolean(R.styleable.ProgressCircleView_showProgressText, true);

        a.recycle();

        mCirclePaint = new Paint();
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setStrokeWidth(mCircleWidth);
        mCirclePaint.setColor(mCircleColor);

        mProgressPaint = new Paint();
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setAntiAlias(true);
        mProgressPaint.setStrokeWidth(mCircleWidth);
        mProgressPaint.setColor(mProgressColor);

        mTextPaint = new Paint();
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(mProgressColor);
        mTextPaint.setTextSize(30f);
    }

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

        float radius = (Math.min(getWidth(), getHeight()) - getPaddingLeft() - getPaddingRight()) / 2;

        canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, mCirclePaint);

        RectF oval = new RectF(getWidth() / 2 - radius, getHeight() / 2 - radius, getWidth() / 2 + radius, getHeight() / 2 + radius);

        canvas.drawArc(oval, -90, 360 * mProgress / 100, false, mProgressPaint);

        if (mShowProgressText) {
            String progressText = mProgress + "%";
            Rect bounds = new Rect();
            mTextPaint.getTextBounds(progressText, 0, progressText.length(), bounds);
            float x = getWidth() / 2 - bounds.width() / 2;
            float y = getHeight() / 2 + bounds.height() / 2;
            canvas.drawText(progressText, x, y, mTextPaint);
        }
    }

    public void setProgress(int progress) {
        if (progress < 0 || progress > 100) {
            throw new IllegalArgumentException("progress must be between 0 and 100");
        }

        mProgress = progress;
        invalidate();
    }
}

在自定义 View 的构造方法中,我们获取自定义属性的值,并初始化画笔。在 onDraw 方法中,我们首先绘制一个圆环,然后根据进度画出圆弧,最后如果需要显示进度文字,则画出进度文字。在 setProgress 方法中,我们会对传进来的进度值进行合法性检查,然后更新进度,并调用 invalidate() 方法来重绘整个圆环。

4、总结

至此,我们已经完成了一个非常炫酷的圆环控件,并讲解了在 Android 中自定义 View 的相关技巧。希望这篇文章能给你带来一些帮助,如果你还想要了解更多关于 Android 自定义 View 的内容,可以继续关注我的博客,在博客中我会持续更新相关的文章。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android自定义View之酷炫圆环(二) - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Favoritevideo是什么文件夹?如何删除Favoritevideo文件夹?

    Favoritevideo是一个文件夹,通常存放着用户最喜爱的视频,可以在不同的软件或设备上找到。如果你想删除这个文件夹,可以按照下面的步骤进行操作: 1. 手动删除 如果您在计算机上保存了Favoritevideo文件夹,则可以通过以下步骤手动删除该文件夹: 打开文件资源管理器并找到Favoritevideo文件夹的位置。 右键单击文件夹并选择“删除”。 …

    other 2023年6月27日
    00
  • 深入解析Java的设计模式编程中的模板方法模式

    深入解析Java的设计模式编程中的模板方法模式 模板方法模式是一种行为设计模式,在Java程序中被广泛地使用,它将一个算法的步骤定义为一组抽象方法,具体实现则由子类来完成。这种模式提供了在框架方法级别上的灵活性,并且允许不同的算法使用相同的框架。 什么是模板方法模式 模板方法模式是一种行为设计模式,它允许我们为实现算法的关键步骤定义一个模板骨架,并允许子类通…

    other 2023年6月27日
    00
  • JDK9为何要将String的底层实现由char[]改成了byte[]

    JDK 9将String的底层实现由char[]改成了byte[]的原因 在JDK 9中,Java的String类的底层实现从使用char[]数组改为了使用byte[]数组。这个改变是为了提高内存使用效率和性能,并且在处理非拉丁字符时能够更好地支持Unicode编码。 1. 内存使用效率 使用byte[]数组作为String的底层实现可以减少内存使用量。在J…

    other 2023年8月2日
    00
  • 带你深入了解java-代理机制

    带你深入了解 Java 代理机制 代理机制是 Java 语言的一个重要特性,它允许我们在运行时生成一个替代某个对象的对象,从而能够控制访问、修改被代理对象的属性或方法。在本文中,我们将深入讲解 Java 的代理机制,包括代理类型、创建方式、使用场景等。 代理类型 Java 语言中有两种代理类型:静态代理和动态代理。 静态代理 静态代理是指在编译时确定代理类和…

    other 2023年6月26日
    00
  • Java基础教程之封装与接口

    Java基础教程之封装与接口 封装 封装是指隐藏对象的属性和实现细节,仅对外暴露有限的接口,控制外部访问对象内部的能力。Java中,封装是通过访问控制来实现的。 访问控制符 Java中有四种访问控制符,分别是public、protected、default、private,它们的访问权限从大到小排列。 public:不受限制,任何地方都可以访问。 prote…

    other 2023年6月25日
    00
  • CAD布局空间如何开视口?CAD布局空间开视口的方法

    CAD布局空间开视口是指在CAD软件中,通过设置视口来显示模型或图纸的特定部分。下面是CAD布局空间开视口的方法的完整攻略: 打开CAD软件并加载你的模型或图纸。 进入布局空间,可以通过点击CAD界面上的“布局”选项卡或使用相应的快捷键。 在布局空间中,选择一个合适的布局页面,例如A4纸张大小。 在布局页面上右键单击,选择“新建视口”或使用相应的快捷键。 在…

    other 2023年9月6日
    00
  • json数据进行sql查询

    json数据进行SQL查询 在现代的应用程序中,JSON(JavaScript Object Notation)已经成为最常用的数据交换格式之一。随着日益增长的JSON数据存储,在许多情况下,我们需要使用SQL查询来检索JSON对象中特定属性的值。在本文中,我们将提供一些关于如何在SQL中使用JSON数据的指导。 使用JSON函数 SQL 2016 引入了几…

    其他 2023年3月28日
    00
  • springboot下pdf生成使用填坑总结

    以下是详细讲解“Spring Boot下PDF生成使用填坑总结”的完整攻略: 步骤1:添加依赖 我们需要在 pom.xml 文件中添加以下依赖: <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId&gt…

    other 2023年5月8日
    00
合作推广
合作推广
分享本页
返回顶部