圓形進度條的模仿3-DrawArc,DrawCircle,DrawText,自定義屬性實例講解

  • 2020 年 10 月 20 日
  • 筆記

前面兩篇中已經講過如何使用drawARC,等,畫其他的圖形的方法的使用也是一樣的,只是參數不同,

同時也講了如何通過xml進行自定義屬性,接下來這篇便是通過實例講解如何實地應用起來,

效果如下,點擊開始時,進度條會開始轉動,點擊停止時會停在轉動的位置,若在次點擊開始時,會從停止

的位置開始轉動。

                                                     

1:這個控制項我們是自定義的,所以定義一個類繼承於view類,必須要寫的兩個構造方法,

2:將要添加的屬性在values下面的xml文件中寫好(方法看上一篇):

3:在layout中將屬性用起來(方法看上篇)

4:回到程式碼中,在xml構造方法中,將自定義的屬性解析出來,(裡面的參數及其理解看上篇,),

 

 5:重寫ondraw方法,繪畫的部分是在該方法裡面實現的,

6:在ondraw方法中畫出自己要畫的圖形,我這裡畫的是一個圓,一個圓弧,以及一個文本

  canvas?.drawCircle(cx,cy,radious,paint)

//畫弧
canvas?.drawArc(mstrokewidth,mstrokewidth,width-mstrokewidth,height-mstrokewidth,
-90f,360f*arc_chang,false,arc_paint)

//畫文本
canvas?.drawText("${text.toInt()}%",width/2f,height/2f+textMove,text_paint)

進度條本身是一個圓環,我是通過設置畫圓的畫筆來實現畫圓環的:通過設置它的填充方式為Stroke,以及
畫筆的寬度寬一點,那麼畫出來就是一個圓環
//圓的畫筆
private val paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.STROKE
strokeWidth = mstrokewidth
}

而我們畫的並不是一個死的東西,是一個在變化的東西,那麼我們就可以設置它的動畫因子,如畫弧的弧度,就可以通過
設置弧度變化的動畫因子來實現,它是從-90度,轉360度轉一圈,那麼我們可以設置一個動畫因子為arc_chang,它的
變化範圍我0到1,在乘以360,就是0到360的範圍變化了,
 //圓弧的動畫因子
val valueAnimator = ValueAnimator.ofFloat(0f,1f).apply {
duration = 2000
addUpdateListener {
myView.arc_chang = it.animatedValue as Float
myView.text = (it.animatedValue as Float)*100
}
}

同理畫文本也可以這樣做,把數字改一下就好了,在啟動動畫
start.setOnClickListener {
if (valueAnimator.isPaused) {
valueAnimator.resume()
}else{
valueAnimator.start()
}
}
stop.setOnClickListener {
valueAnimator.pause()

}

GitHub連接://github.com/luofangli/Circle_progress_bar

整體的程式碼
1:values文件中的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myview">
//圓環
<attr name="Color" format="color|reference"/>
//進度圓環
<attr name="forColor" format="color|reference"/>
//字體
<attr name="android:textColor"/>
</declare-styleable>
</resources>

2:layout中
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="//schemas.android.com/apk/res/android"
xmlns:app="//schemas.android.com/apk/res-auto"
xmlns:tools="//schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<com.example.myapplication.myview
android:id="@+id/myView"
android:layout_width="200dp"
android:layout_height="200dp"

android:textColor="@color/colorAccent"
app:Color="@color/colorGray"
app:forColor="@color/colorPrimary"

app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:text="開始"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/stop"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/myView" />

<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/start"
app:layout_constraintTop_toTopOf="@+id/start" />


</androidx.constraintlayout.widget.ConstraintLayout>

3:自定義view類中
package com.example.myapplication

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import java.util.jar.Attributes

class myview:View {
//圓的圓心
private var cx= 0f
private var cy = 0f
//半徑
private var radious = 0f
//畫筆的粗細
private val mstrokewidth = 50f
//圓中心的文本
var text = 0f
set(value) {
field = value
invalidate()
}
//圓弧的動畫因子
var arc_chang = 0.00f
set(value) {
field = value
invalidate()
}


//圓的畫筆
private val paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.STROKE
strokeWidth = mstrokewidth
}
//圓弧的畫筆
private val arc_paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.STROKE
strokeWidth = mstrokewidth
}
//畫筆向下移動的距離
private var textMove = 0f
//文本的畫筆
private val text_paint = Paint().apply {
color = Color.BLUE
style = Paint.Style.FILL
textSize = 50f
textAlign = Paint.Align.CENTER
textMove = (descent()-ascent())/2f
}



//畫筆的顏色
var paint_color = Color.BLUE
set(value) {
field = value
paint.color = value
}
//畫圓弧的顏色
var arc_color = Color.GREEN
set(value) {
field = value
arc_paint.color = value
}
//字體顏色
var text_color = Color.GREEN

constructor(context: Context):super(context){}
//程式碼
constructor(context: Context,attributes: AttributeSet?):super(context,attributes){
//1:簡析
val typedArray = context.obtainStyledAttributes(attributes,
R.styleable.myview)
//獲取屬性
paint_color = typedArray.getColor(R.styleable.myview_Color,Color.GRAY)
arc_color = typedArray.getColor(R.styleable.myview_forColor,Color.GREEN)
text_color = typedArray.getColor(R.styleable.myview_android_textColor,
Color.GREEN)

//釋放記憶體
typedArray.recycle()
}

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
cx = width/2f
cy = height/2f
radious = Math.min(width,height)/2f - mstrokewidth
}
override fun onDraw(canvas: Canvas?) {
canvas?.drawCircle(cx,cy,radious,paint)
//畫弧
canvas?.drawArc(mstrokewidth,mstrokewidth,width-mstrokewidth,height-mstrokewidth,
-90f,360f*arc_chang,false,arc_paint)

//畫文本
canvas?.drawText("${text.toInt()}%",width/2f,height/2f+textMove,text_paint)

}
}

4:mainActivity類中
package com.example.myapplication

import android.animation.Animator
import android.animation.ValueAnimator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ObjectInputValidation

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//圓弧的動畫因子
val valueAnimator = ValueAnimator.ofFloat(0f,1f).apply {
duration = 2000
addUpdateListener {
myView.arc_chang = it.animatedValue as Float
myView.text = (it.animatedValue as Float)*100
}
}
start.setOnClickListener {
if (valueAnimator.isPaused) {
valueAnimator.resume()
}else{
valueAnimator.start()
}
}
stop.setOnClickListener {
valueAnimator.pause()

}


}
}