1:效果
一运行起来,红色是下载的部分,蓝色是为下载部分,下载完之后先缩成一个椭圆,在缩成一个圆
GitHub地址:https://github.com/luofangli/MyDrawProgress
详细代码:
<?xml version="1.0" enCoding="utf-8"?>
<androIDx.constraintlayout.Widget.ConstraintLayout 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:layout_wIDth="match_parent"
androID:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.my.CustomProgress
androID:ID="@+ID/custom_progress"
androID:layout_wIDth="0dp"
androID:layout_height="100dp"
androID:layout_marginStart="20dp"
androID:layout_margintop="200dp"
androID:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constrainttop_totopOf="parent" />
</androIDx.constraintlayout.Widget.ConstraintLayout>
package com.example.my
import androID.animation.AnimatorSet
import androID.animation.ValueAnimator
import androID.content.Context
import androID.graphics.Canvas
import androID.graphics.color
import androID.graphics.Paint
import androID.graphics.Path
import androID.util.AttributeSet
import androID.util.Log
import androID.vIEw.VIEw
class CustomProgress : VIEw {
//运行起来的背景画笔
private val paintFirst:Paint by lazy {
Paint().apply {
style = Paint.Style.FILL
color = color.BLUE
}
}
//移动的进度条的画笔
private val paintSecond:Paint by lazy {
Paint().apply {
style = Paint.Style.FILL
color = color.RED
}
}
//勾勾的画笔
private val paintPath:Paint by lazy {
Paint().apply {
style = Paint.Style.stroke
color = color.WHITE
strokeWIDth = 6f
}
}
//勾勾的路径
private val path:Path by lazy {
Path().apply {
moveto(startpathX,startpathY)
lineto(centerpathX,centerpathY)
}
}
//定义动画因子
//路径移动的起点和尾点
private var startpathX = 0f
private var startpathY = 0f
private var centerpathX = 0f
private var centerpathY = 0f
//两边向中间移动成一个圆的距离
private var centerdistance = 0f
//圆矩形圆的半径
private var radius = 0f
//进度条的总长度
private var progressLength = 0f
//进度条下载过程中的动画因子
private var alldistance = 0f
//外部下载的进度
var loadProgress = 0f
set(value) {
fIEld = value
progressGo(fIEld)
}
constructor(context: Context):super(context){}
constructor(context: Context,attributeSet: AttributeSet):super(context,attributeSet){}
overrIDe fun onSizeChanged(w: Int, h: Int, olDW: Int, oldh: Int) {
super.onSizeChanged(w, h, olDW, oldh)
progressLength = measureDWIDth.tofloat()
// startpathX = measureDWIDth/2f-measuredHeight*3/10f
// startpathY = measuredHeight/2f
// centerpathX = measureDWIDth/2f-measuredHeight*3/10f
// centerpathY = measuredHeight/2f
startpathX = measureDWIDth/2f-radius/2
startpathY = measuredHeight/2f
centerpathX =measureDWIDth/2f-radius/2
centerpathY = measuredHeight/2f
}
overrIDe fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
//运行起来就有的背景
canvas?.drawRoundRect(alldistance,0f,measureDWIDth.tofloat(),measuredHeight.tofloat(),
0f,0f,paintFirst)
//移动的进度条
canvas?.drawRoundRect(0f+centerdistance,0f,alldistance-centerdistance,measuredHeight.tofloat(),
radius,radius,paintSecond)
//画勾勾
canvas?.drawPath(path,paintPath)
}
//进度条前进的动画
private fun progressGo(load:float){
alldistance = progressLength*load
//下载完之后执行
if (alldistance == progressLength){
afterProgress()
}
invalIDate()
}
//进度条完了之后的动画
private fun afterProgress(){
//如果进度条完了则开启下面的动画
//由长方形变成一个圆矩形的动画
val radiusValueAnimator = ValueAnimator.offloat(0f,measuredHeight/2f).apply {
duration = 2000
addUpdateListener {
Log.v("lfl","长方形变成圆矩形")
val value = it.animatedValue as float
radius = value
invalIDate()
}
}
//由两边向中间移动成一个圆的距离
val centerValueAnimator = ValueAnimator.offloat(0f,(measureDWIDth-measuredHeight)/2f).apply {
duration = 2000
addUpdateListener {
Log.v("lfl","从两边缩成一个圆")
val value = it.animatedValue as float
centerdistance = value
invalIDate()
}
}
//画钩钩
// measureDWIDth/2f-measuredHeight*3/20f,
val pathXValueAnimator = ValueAnimator.offloat(measureDWIDth/2f-radius/2f,
measureDWIDth/2f+radius/2f).apply {
duration = 2000
addUpdateListener {
val value = it.animatedValue as float
centerpathX = value
Log.v("lfl","勾勾尾巴的位置X:$centerpathX")
invalIDate()
}
}
val pathYValueAnimator = ValueAnimator.offloat(measuredHeight/2f,
measuredHeight/2f+radius/2f,
measuredHeight/2f-radius/2f).apply {
duration = 2000
addUpdateListener {
val value = it.animatedValue as float
centerpathY = value
invalIDate()
}
}
val path = AnimatorSet().apply {
playTogether(pathXValueAnimator,pathYValueAnimator)
Log.v("lfl","圆的区域为:左:${measureDWIDth/2-radius},上:${measuredHeight/2-radius}," +
"右:${measureDWIDth/2+radius},下:${measuredHeight/2+radius}")
}
val ValueAnimator = AnimatorSet().apply {
playSequentially(radiusValueAnimator,centerValueAnimator)
}
val all = AnimatorSet().apply {
playSequentially(ValueAnimator,path)
}.start()
}
}
package com.example.my
import androID.animation.ValueAnimator
import androIDx.appcompat.app.AppCompatActivity
import androID.os.Bundle
import androID.util.Log
import kotlinx.androID.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
overrIDe fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentVIEw(R.layout.activity_main)
ValueAnimator.offloat(0f,1f).apply {
duration = 1000
addUpdateListener {
val value = it.animatedValue as float
custom_progress.loadProgress = value
}
}.start()
}
}
总结
以上是内存溢出为你收集整理的自定义进度条Android,kotlin全部内容,希望文章能够帮你解决自定义进度条Android,kotlin所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)