自定义view实现半圆弧进度条

Android自定义圆弧进度条(半圆进度条) 圆弧渐变色进度条带指示 圆弧宽高可自由修改 Android 自定义圆弧进度条,支持设置为圆形进度条,弧度圆形渐变色,进度指示条,进度文字。 阅读详情


一、效果图

效果图


二、使用步骤

1.新建CustomView继承自view

代码如下:

public class CustomView extends View {

}

2.定义变量

代码如下:

	//外圆弧
    private Paint outPaint;
	//内圆弧
    private Paint innerPaint;
	//文字
    private Paint mTextPaint;
    //矩形
    private RectF oval;

    //最大进度
    private int max = 10;
    //当前进度
    private int progress = 6;
    //文本内容
    private String text = "得分 "+ progress + "/" + max;
    //圆弧宽度
    private int roundWidth = 40;
	//圆点
    private int mCircleRadius = SizeUtils.dp2px(6);
    private Paint mCirclePaint;
    private float[] pos =new float[2];
   
    private int viewWidth; //宽度--控件所占区域

    private float nowPro = 0;//用于动画

    private ValueAnimator animator;


3.构造函数

public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs, context);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs, context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initAttrs(attrs, context);
    }

4.构造方法

public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }


5.初始化数据

private void initAttrs(AttributeSet attr, Context context) {

        outPaint = new Paint();
        outPaint.setColor(Color.parseColor("#F5F6FA"));
        outPaint.setAntiAlias(true);
        outPaint.setStyle(Paint.Style.STROKE);
        outPaint.setStrokeCap(Paint.Cap.ROUND);
        outPaint.setStrokeWidth(SizeUtils.dp2px(12));

        innerPaint = new Paint();
        innerPaint.setColor(Color.parseColor("#667CFF"));
        innerPaint.setAntiAlias(true);
        innerPaint.setStyle(Paint.Style.STROKE);
        innerPaint.setStrokeCap(Paint.Cap.ROUND);
        innerPaint.setStrokeWidth(SizeUtils.dp2px(12));

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.parseColor("#131936"));
        mTextPaint.setFakeBoldText(true);
        mTextPaint.setTextSize(SizeUtils.sp2px(20));

        //动画
        animator = ValueAnimator.ofFloat(0, progress);
        animator.setDuration(1800);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                nowPro = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();
    }


6.onMeasure()

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));

    }

7.onSizeChanged()

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        viewWidth = w;//得到宽度以此来计算控件所占实际大小
        //计算画布所占区域
        oval = new RectF();
        oval.left = roundWidth + getPaddingLeft();
        oval.top = roundWidth + getPaddingTop();
        oval.right = viewWidth - roundWidth - getPaddingRight();
        oval.bottom = viewWidth - roundWidth - getPaddingBottom();

    }

8.onDraw()

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


        Path outerPath = new Path();
        outerPath.arcTo(oval,180,180);
        canvas.drawPath(outerPath,outPaint);

        SweepGradient sweepGradient = new SweepGradient(getWidth()/2,getWidth()/2,Color.parseColor("#FFFFFF"),Color.parseColor("#0047F7"));
        innerPaint.setShader(sweepGradient);

        canvas.drawArc(oval, 180, 180 * nowPro / max, false, innerPaint); //绘制圆弧

        mCirclePaint = new Paint();
        mCirclePaint.setColor(Color.WHITE);
        mCirclePaint.setStyle(Paint.Style.FILL);

        PathMeasure pathMeasure = new PathMeasure(outerPath,false);
        boolean posTan = pathMeasure.getPosTan(pathMeasure.getLength() * nowPro / max, pos, null);
        canvas.drawCircle(pos[0],pos[1],mCircleRadius,mCirclePaint);

        float textWidth = mTextPaint.measureText(text);
        canvas.drawText(text, viewWidth / 2 - textWidth / 2, viewWidth / 2, mTextPaint);
    }

9.xml文件

<com.wuchen.viewdemo.CustomView
        android:id="@+id/customView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

三、完整代码(附Demo地址)

package com.wuchen.juexiaofakao;

import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import com.blankj.utilcode.util.SizeUtils;

public class CustomView extends View {

    private Paint outPaint;

    private Paint innerPaint;

    private Paint mTextPaint;

    private RectF oval;

    //最大进度
    private int max = 10;
    //当前进度
    private int progress = 6;
    //文本内容
    private String text = "得分 "+ progress + "/" + max;
    //圆弧宽度
    private int roundWidth = 40;

    private int mCircleRadius = SizeUtils.dp2px(6);
    private Paint mCirclePaint;
    private float[] pos =new float[2];
    private final int[] colors = {Color.parseColor("#95ACFF"),Color.parseColor("#4379FF")};

    private int viewWidth; //宽度--控件所占区域

    private float nowPro = 0;//用于动画


    private ValueAnimator animator;


    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(attrs, context);
    }

    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(attrs, context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initAttrs(attrs, context);
    }

    public int getMax() {
        return max;
    }

    public void setMax(int max) {
        this.max = max;
    }

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    private void initAttrs(AttributeSet attr, Context context) {

        outPaint = new Paint();
        outPaint.setColor(Color.parseColor("#F5F6FA"));
        outPaint.setAntiAlias(true);
        outPaint.setStyle(Paint.Style.STROKE);
        outPaint.setStrokeCap(Paint.Cap.ROUND);
        outPaint.setStrokeWidth(SizeUtils.dp2px(12));

        innerPaint = new Paint();
        innerPaint.setColor(Color.parseColor("#667CFF"));
        innerPaint.setAntiAlias(true);
        innerPaint.setStyle(Paint.Style.STROKE);
        innerPaint.setStrokeCap(Paint.Cap.ROUND);
        innerPaint.setStrokeWidth(SizeUtils.dp2px(12));

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(Color.parseColor("#131936"));
        mTextPaint.setFakeBoldText(true);
        mTextPaint.setTextSize(SizeUtils.sp2px(20));

        //动画
        animator = ValueAnimator.ofFloat(0, progress);
        animator.setDuration(1800);
        animator.setInterpolator(new DecelerateInterpolator());
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                nowPro = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        viewWidth = w;//得到宽度以此来计算控件所占实际大小
        //计算画布所占区域
        oval = new RectF();
        oval.left = roundWidth + getPaddingLeft();
        oval.top = roundWidth + getPaddingTop();
        oval.right = viewWidth - roundWidth - getPaddingRight();
        oval.bottom = viewWidth - roundWidth - getPaddingBottom();

    }

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


        Path outerPath = new Path();
        outerPath.arcTo(oval,180,180);
        canvas.drawPath(outerPath,outPaint);

        SweepGradient sweepGradient = new SweepGradient(getWidth()/2,getWidth()/2,Color.parseColor("#FFFFFF"),Color.parseColor("#0047F7"));
        innerPaint.setShader(sweepGradient);

        canvas.drawArc(oval, 180, 180 * nowPro / max, false, innerPaint); //绘制圆弧

        mCirclePaint = new Paint();
        mCirclePaint.setColor(Color.WHITE);
        mCirclePaint.setStyle(Paint.Style.FILL);

        PathMeasure pathMeasure = new PathMeasure(outerPath,false);
        boolean posTan = pathMeasure.getPosTan(pathMeasure.getLength() * nowPro / max, pos, null);
        canvas.drawCircle(pos[0],pos[1],mCircleRadius,mCirclePaint);

        float textWidth = mTextPaint.measureText(text);
        canvas.drawText(text, viewWidth / 2 - textWidth / 2, viewWidth / 2, mTextPaint);
    }
}

Demo地址

android 固定进度刻度,Android 效果之带刻度的半圆环进度条小述 一、背景最近准备要做一个类似仪表盘样式的半圆环带刻度可拖动的进度条来展示和设置温度,网上找了找demo,都和实际的需求有点区别,感觉这种功能实现起来不难,就索性自己弄了一个。二、正文在开始之前,我们来看下实际的运行效果,看看能不能满足正在查找资料的小伙伴的项目需求:效果就是这样的啦,没什么特别的地方,我们来看下实现方法吧,如果对于自定义View的流程还有些不清楚,可以查看一下自定义简单View及获... 阅读详情

相关推荐

Android自定义View——从零开始实现圆形进度条

以前老是用别人造的轮子,知其然不知其所以然,有时看懂了别人写的过多几个月又忘了,遂来开个坑把一步步实现和思路写下来,弄成一个系列。本篇只要讲的是Android自定义圆形进度条

AnliaLee的博客 1万+

Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改

Android自定义半圆进度条 半圆渐变色进度条带指示 半圆开口大小可自由修改 首先我们来看下效果图 不同的开口大小只需要修改一个参数即可 半圆1: 半圆2: 半圆3: 如果是你想要的效果,就直接滑动到文章底部,下载源码,然后结合本文章操作说明集成到自己的项目中吧 如果集成 第一步: 下载项目解压,然后用as打开。 第二步: 复制SemicircleProgr

简雨山舍 7877

Android自定义View实现彩虹进度条(带动画)

Android自定义View实现带动画的彩虹进度条

m0_74448051的博客 1813

使用Canvas绘制自定义View——三重半圆环进度条

android三重自定义半圆进度环

qq_40694393的博客 823

Android 自定义View(二)实现环形进度条

自定义View实现环形进度条一、前言二、实现效果1、源码下载:[点击下载](https://github.com/jaynm888/CustomizeView)2、效果图展示3、步骤分析三、代码实现1、自定义属性2、绘制圆环3、绘制圆弧4、更新进度条5、绘制文本总结 一、前言 Android 自定义 View 是高级进阶不可或缺的内容,日常工作中,经常会遇到产品、UI 设计出花里胡哨的界面。当系统自带的控件不能满足开发需求时,就只能自己动手撸一个效果。 本文就带自定义 View 初学者手动撸一个效果,通过自

一名互联网时代苟且偷生的 Android码农 1249

Android-自定义ProgressBar实现圆弧进度条

继承于ProgressBar实现,保留了Progressbar的特性,源码在文尾。。参数 name format description borderWidth integer 圆弧边框的宽度 progressStyle tick/arc 进度条类型,tick为带刻度的 radius integer 半径 arcbgColor color 圆

Zeeeeeeee的博客 2319

Android自定义view 实现半圆环

http://blog.youkuaiyun.com/chenzheng8975/article/details/59739625 1.自定义属性 declare-styleable name="SemicircleView"> attr name="radius" format="dimension" /> attr name="strokeWidth

mengzhengjie的专栏 920

Android彩虹圆弧进度条自定义视图

本文还有配套的精品资源,点击获取 简介:在Android开发中,“彩虹进度条(圆弧进度条)”提供了一种创新的用户界面组件,通过自定义视图 CirqueControlView 实现多彩和动态的圆弧形状进度条。开发者可通过重写 onDraw() 方法进行图形绘制,并通过处理触摸事件来实现进度条的可拖动特性。本项目还展示如何创建具有独立控制进度的多条弧...

weixin_33256096的博客 1155

自定义view实现半圆环

1.自定义属性 declare-styleable name="SemicircleView"> attr name="radius" format="dimension" /> attr name="strokeWidth" format="dimension" /> attr name="bgArcColor" format="color" /

TTHHVV的博客 432

Android自定义半圆弧形ProgressBar实现

在Android开发中,创建一个具有吸引力的用户界面往往需要自定义组件来满足特定的设计需求。本章节将引导您了解如何实现一个自定义的类。我们将从基础概念开始,深入探讨自定义视图的构建过程,并最终展示如何创建一个既美观又实用的进度条控件。自定义视图的实现可以通过继承View类并重写其方法来完成。这不仅增加了代码的可维护性,同时也提供了更大的灵活性和扩展性。接下来,我们将通过实例演示如何继承View类,一步步构建出一个半圆弧形的。

weixin_35754962的博客 688

Android自定义圆弧进度条的手动控制教程

在Android开发中,自定义View的创建是扩展UI组件功能和提升用户体验的重要手段。我们开始这一旅程的第一步是定义一个新的Java类,该类继承自View基类。// 构造函数,可以用来初始化画笔等属性init();init();init();// 初始化画笔和参数,比如进度条的颜色,宽度等// 实现onDraw方法,将在此方法中绘制圆弧进度条@Override// 绘制逻辑在这个基础类中,我们实现了三个构造函数,它们允许在不同的上下文中创建视图实例。init()

weixin_42509507的博客 973

Android自定义View:圆环带数字百分比的进度条

分享一个自己制作的Android自定义View。是一个圆环形状的反映真实进度的进度条,百分比的进度文字跟随已完成进度的圆弧转动。先来一张效果图。 先说一下思路:这个View一共分为三部分:第一部分也就是灰色的圆环部分,代表未完成的进度;第二部分是蓝色的圆弧部分,代表已经完成的进度;第三部分是红色的百分比的数字百分比文本,显示当前确切的完成进度。 下面是View的编写思路: ①:定义三

飞天神猪 6604

创建自定义圆弧加载进度条

在现代移动应用和网页设计中,自定义加载进度条是提升用户体验的关键因素之一。本章主要探讨如何创建一个自定义的圆弧加载进度条,并在设计过程中实现继承机制,以保证高度的可重用性和扩展性。创建自定义圆弧加载进度条的第一步是继承一个基础视图类,例如在Android开发中,通常是View类。这样做可以让我们完全控制进度条的绘制和行为。// 构造函数和初始化代码。

weixin_35903223的博客 997

Android 自定义View实现环形带刻度的进度条

本篇文章讲的是自定义View实现环形带刻度的进度条。和往常一样,主要还是想总结一下自定义View实现环形带刻度的进度条的开发过程以及一些需要注意的地方。 按照惯例,我们先来看看效果图 一、我们如何来实现这样一个环形刻度进度条: 首先,需要绘制一个灰色的环形刻度尺底图,来作为未填充时的进度条; 然后,根据传入的当前进度值,绘制填充时的进度圆弧; 其次,根据进度值绘制文字提示; 最后...

Angelica 6120

Android自定义半圆进度条

android自定义半圆进度条,可以自己根据里面备注的参数,调整半圆的长度。这里是使用说明:http://blog.youkuaiyun.com/beibaokongming/article/details/79002646

Android自定义带动画的半圆环型进度效果

本文实例为大家分享了Android半圆环型进度效果的具体代码,供大家参考,具体内容如下 package com.newair.ondrawtext; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import androi

Android:自定义View实现绚丽的圆形进度条

Android:自定义View实现绚丽的圆形进度条

books1958的专栏 8706

Android半圆弧形ProgressBar实现[代码]

本文详细介绍了在Android开发中如何实现一个自定义的半圆弧形ProgressBar。通过创建自定义的CircleProgressBar类并重写onDraw()方法,实现了半圆弧形进度条的绘制和百分比文本的动态更新。文章涵盖了从基础概念到具体实现的完整过程,包括画布旋转角度设置、路径形状定义、进度计算与绘制方法。此外,还讲解了如何在XML布局中引入自定义ProgressBar以及在build.gradle中添加依赖的步骤。该实践涉及Android图形绘制、自定义View开发和UI组件交互等核心知识点,为开发者提供了完整的自定义进度条实现方案。

上一篇: Binder机制详解(三)
下一篇: 帧动画和补间动画的使用
浮空over
博客等级 码龄7年 6粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值