Android studio realizes custom circular progress bar with scale progress bar step counting effect speedometer water ripple effect

Original link

renderings

Insert image description here
Insert image description here
Insert image description here
After clicking reset:
Insert image description here
the project has achieved a total of three circular progress bar effects

  1. CircleProgress: circular progress bar, which can achieve the effect of imitating QQ Health Pedometer. It supports configuring the background color, width and starting angle of the progress bar, and supports the gradient of the progress bar.
  2. DialProgress: Similar to CircleProgress, but supports scale
  3. WaveProgress: A circular progress bar that implements a water ripple effect. It does not support gradient and starting angle configuration. If you need this function, you can refer to CircleProgress to implement it yourself.
    All progress bars can be manually touched to change the percentage. For
    my code and dependencies, I did not add the leakcanary library. There is no app.activity
    dependency. I added it myself after an error occurred. It may not be applicable to all projects.
 buildTypes {
   
    
    
        debug {
   
    
    
            buildConfigField "boolean", "DEBUG", "true"

        }
        release {
   
    
    
            buildConfigField "boolean", "DEBUG", "false"
            }
  defaultConfig {
   
    
    
   buildConfigField "boolean", "DEBUG", "true"
   }

values /

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 是否开启抗锯齿 -->
    <attr name="antiAlias" format="boolean" />
    <!-- 圆弧起始角度,3点钟方向为0,顺时针递增,小于0或大于360进行取余 -->
    <attr name="startAngle" format="float" />
    <!-- 圆弧度数 -->
    <attr name="sweepAngle" format="float" />
    <!-- 设置动画时间 -->
    <attr name="animTime" format="integer" />
    <!-- 绘制内容的数值 -->
    <attr name="maxValue" format="float" />
    <attr name="value" format="float" />
    <!-- 绘制内容的单位 -->
    <attr name="unit" format="string|reference" />
    <attr name="unitSize" format="dimension" />
    <attr name="unitColor" format="color|reference" />
    <!-- 绘制内容相应的提示语 -->
    <attr name="hint" format="string|reference" />
    <attr name="hintSize" format="dimension" />
    <attr name="hintColor" format="color|reference" />
    <!-- 精度,默认为0 -->
    <attr name="precision" format="integer" />
    <attr name="valueSize" format="dimension" />
    <attr name="valueColor" format="color|reference" />
    <!-- 圆弧颜色,设置多个可实现渐变 -->
    <attr name="arcColor1" format="color|reference" />
    <attr name="arcColor2" format="color|reference" />
    <attr name="arcColor3" format="color|reference" />
    <!-- 背景圆弧颜色,默认白色 -->
    <attr name="bgArcColor" format="color|reference" />
    <!-- 圆弧宽度 -->
    <attr name="arcWidth" format="dimension" />
    <!-- 圆弧颜色, -->
    <attr name="arcColors" format="color|reference" />
    <!-- 文字的偏移量。相对于圆半径而言,默认三分之一 -->
    <attr name="textOffsetPercentInRadius" format="float" />

    <!-- 圆形进度条 -->
    <declare-styleable name="CircleProgressBar">
        <attr name="antiAlias" />
        <attr name="startAngle" />
        <attr name="sweepAngle" />
        <attr name="animTime" />
        <attr name="maxValue" />
        <attr name="value" />
        <attr name="precision" />
        <attr name="valueSize" />
        <attr name="valueColor" />
        <attr name="textOffsetPercentInRadius" />
        <!-- 绘制内容相应的提示语 -->
        <attr name="hint" />
        <attr name="hintSize" />
        <attr name="hintColor" />
        <!-- 绘制内容的单位 -->
        <attr name="unit" />
        <attr name="unitSize" />
        <attr name="unitColor" />
        <!-- 圆弧宽度 -->
        <attr name="arcWidth" />
        <attr name="arcColors" />
        <!-- 背景圆弧颜色 -->
        <attr name="bgArcColor" />
        <!-- 背景圆弧宽度 -->
        <attr name="bgArcWidth" format="dimension" />
    </declare-styleable>

    <declare-styleable name="DialProgress">
        <attr name="antiAlias" />
        <attr name="startAngle" />
        <attr name="sweepAngle" />
        <attr name="animTime" />
        <attr name="maxValue" />
        <attr name="value" />
        <attr name="precision" />
        <attr name="valueSize" />
        <attr name="valueColor" />
        <attr name="textOffsetPercentInRadius" />
        <!-- 绘制内容的单位 -->
        <attr name="unit" />
        <attr name="unitSize" />
        <attr name="unitColor" />
        <!-- 绘制内容相应的提示语 -->
        <attr name="hint" />
        <attr name="hintSize" />
        <attr name="hintColor" />
        <!-- 圆弧的宽度 -->
        <attr name="arcWidth" />
        <!-- 刻度的宽度 -->
        <attr name="dialWidth" format="dimension|reference" />
        <!-- 刻度之间的间隔 -->
        <attr name="dialIntervalDegree" format="integer" />
        <!-- 圆弧颜色, -->
        <attr name="arcColors" />
        <!-- 背景圆弧线颜色 -->
        <attr name="bgArcColor" />
        <!-- 刻度线颜色 -->
        <attr name="dialColor" format="color|reference" />
    </declare-styleable>

    <declare-styleable name="WaveProgress">
        <!-- 是否开启抗锯齿 -->
        <attr name="antiAlias" />
        <!-- 深色水波动画时间 -->
        <attr name="darkWaveAnimTime" format="integer" />
        <!-- 浅色水波动画时间 -->
        <attr name="lightWaveAnimTime" format="integer" />
        <!-- 最大值 -->
        <attr name="maxValue" />
        <!-- 当前值 -->
        <attr name="value" />
        <attr name="valueColor" />
        <attr name="valueSize" />
        <!-- 绘制内容相应的提示语 -->
        <attr name="hint" />
        <attr name="hintSize" />
        <attr name="hintColor" />
        <!-- 圆环宽度 -->
        <attr name="circleWidth" format="dimension" />
        <!-- 圆环颜色 -->
        <attr name="circleColor" format="color|reference" />
        <!-- 背景圆环颜色 -->
        <attr name="bgCircleColor" format="color|reference" />
        <!-- 锁定水波不随圆环进度改变,默认锁定在50%-->
        <attr name="lockWave" format="boolean" />
        <!-- 水波数量 -->
        <attr name="waveNum" format="integer" />
        <!-- 水波高度,峰值和谷值之和 -->
        <attr name="waveHeight" format="dimension" />
        <!-- 深色水波颜色 -->
        <attr name="darkWaveColor" format="color|reference" />
        <!-- 是否显示浅色水波 -->
        <attr name="showLightWave" format="boolean" />
        <!-- 浅色水波颜色 -->
        <attr name="lightWaveColor" format="color|reference" />
        <!-- 浅色水波的方向 -->
        <attr name="lightWaveDirect" format="enum">
            <enum name="L2R" value="0" />
            <enum name="R2L" value="1" />
        </attr>
    </declare-styleable>
</resources>

color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>

    <color name="dark">#803cbcb7</color>
    <color name="light">#800de6e8</color>

    <color name="green">#00FF00</color>
    <color name="blue">#EE9A00</color>
    <color name="red">#EE0000</color>

    <integer-array name="gradient_arc_color">
        <item>@color/green</item>
        <item>@color/blue</item>
        <item>@color/red</item>
    </integer-array>
</resources>

dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="small">5dp</dimen>
    <dimen name="medium">10dp</dimen>
    <dimen name="normal">15dp</dimen>
    <dimen name="large">20dp</dimen>
    <dimen name="xlarge">25dp</dimen>
    <dimen name="xxlarge">30dp</dimen>

    <!-- text size -->
    <dimen name="text_size_35">35sp</dimen>
    <dimen name="text_size_34">34sp</dimen>
    <dimen name="text_size_33">33sp</dimen>
    <dimen name="text_size_32">32sp</dimen>
    <dimen name="text_size_31">31sp</dimen>
    <dimen name="text_size_30">30sp</dimen>
    <dimen name="text_size_29">29sp</dimen>
    <dimen name="text_size_28">28sp</dimen>
    <dimen name="text_size_26">26sp</dimen>
    <dimen name="text_size_25">25sp</dimen>
    <dimen name="text_size_24">24sp</dimen>
    <dimen name="text_size_23">23sp</dimen>
    <dimen name="text_size_22">22sp</dimen>
    <dimen name="text_size_21">21sp</dimen>
    <dimen name="text_size_20">20sp</dimen>
    <dimen name="text_size_19">19sp</dimen>
    <dimen name="text_size_18">18sp</dimen>
    <dimen name="text_size_17">17sp</dimen>
    <dimen name="text_size_16">16sp</dimen>
    <dimen name="text_size_15">15sp</dimen>
    <dimen name="text_size_14">14sp</dimen>
    <dimen name="text_size_13">13sp</dimen>
    <dimen name="text_size_12">12sp</dimen>
    <dimen name="text_size_11">11sp</dimen>
    <dimen name="text_size_10">10sp</dimen>
    <dimen name="text_size_9">9sp</dimen>
    <dimen name="text_size_8">8sp</dimen>
    <dimen name="text_size_7">7sp</dimen>

    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>

layout /

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
    tools:context="com.example.circularwaterripple.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_reset_all"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="重置" />

        <com.example.circularwaterripple.CircleProgress
            android:id="@+id/circle_progress_bar1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            app:antiAlias="true"
            app:arcWidth="@dimen/small"
            app:bgArcColor="@color/colorAccent"
            app:bgArcWidth="@dimen/small"
            app:hint="截止当前已走"
            app:hintSize="15sp"
            app:maxValue="10000"
            app:startAngle="135"
            app:sweepAngle="270"
            app:unit="步"
            app:unitSize="15sp"
            app:value="10000"
            app:valueSize="25sp"/>

        <com.example.circularwaterripple.CircleProgress
            android:id="@+id/circle_progress_bar2"
            android:layout_width="100dp"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal"
            app:antiAlias="true"
            app:arcWidth="@dimen/small"
            app:bgArcColor="@color/colorAccent"
            app:bgArcWidth="@dimen/small"
            app:hint="百分比"
            app:hintSize="@dimen/text_size_15"
            app:maxValue="100"
            app:startAngle="135"
            app:sweepAngle="270"
            app:textOffsetPercentInRadius="0.5"
            app:unit="%"
            app:unitSize="@dimen/text_size_15"
            app:value="75"
            app:valueSize="@dimen/text_size_20"
            tools:ignore="MissingClass" />

        <com.example.circularwaterripple.CircleProgress
            android:id="@+id/circle_progress_bar3"
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:layout_gravity="center_horizontal"
            app:antiAlias="true"
            app:arcWidth="@dimen/small"
            app:bgArcColor="@android:color/darker_gray"
            app:bgArcWidth="@dimen/small"
            app:hint="当前进度"
            app:hintSize="@dimen/text_size_25"
            app:maxValue="100"
            app:startAngle="270"
            app:sweepAngle="360"
            app:unit="%"
            app:unitSize="@dimen/text_size_25"
            app:value="100"
            app:valueSize="@dimen/text_size_35" />

        <com.example.circularwaterripple.DialProgress
            android:id="@+id/dial_progress_bar"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_gravity="center_horizontal"
            android:padding="@dimen/medium"
            app:animTime="1000"
            app:arcColors="@array/gradient_arc_color"
            app:arcWidth="@dimen/large"
            app:dialIntervalDegree="3"
            app:dialWidth="2dp"
            app:hint="当前时速"
            app:hintSize="@dimen/text_size_25"
            app:maxValue="300"
            app:startAngle="135"
            app:sweepAngle="270"
            app:unit="km/h"
            app:unitSize="@dimen/text_size_25"
            app:value="300"
            app:valueSize="@dimen/text_size_35" />

        <com.example.circularwaterripple.WaveProgress
            android:id="@+id/wave_progress_bar"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_gravity="center_horizontal"
            app:darkWaveAnimTime="1000"
            app:darkWaveColor="@color/dark"
            app:lightWaveAnimTime="2000"
            app:lightWaveColor="@color/light"
            app:lightWaveDirect="R2L"
            app:lockWave="false"
            app:valueSize="@dimen/text_size_35"
            app:waveHeight="30dp"
            app:waveNum="1"
            tools:ignore="ExtraText" />
    </LinearLayout>
</ScrollView>

activity.test.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns

Guess you like

Origin blog.csdn.net/weixin_74239923/article/details/132697166