学习|Android中实现进度条按钮功能(kotlin)
- 2019 年 12 月 11 日
- 笔记
本文长度为1029字,预计阅读4分钟
Android中实现按钮进度条
前面几章做了检测TTS及怎么样进度条下载的文章,原想结合几个知识点做一个实战操作,模仿应用宝等手机助手的那种列表下载方式,计划中发现有一环是需要实现个一按钮进度条的方式,看了看以前没有相关的东西,那这篇我们就在看看Android怎么实现按钮进度条的功能。
实现效果

实现思路
要实现ProgressBar加上Button的方式,我们需要自定义类继承自View
然后在进度条滚动的时候进行样式布局的重画
创建xml的自定义属性和点击的接口监听事件
实现按钮进度条,并重新按钮的事件
划重点
我这里实现的是一个简单的方式,可以在这个基础上加上自己的一些新的设计,比如说加载进度条时的颜色和背景色重设,按钮在不同状态下的不同颜色,进度条中状态的监听等方法实现。
代码演示

ProgressButton
package dem.vac.progressbutton import android.annotation.SuppressLint import android.content.Context import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import android.graphics.RectF import android.util.AttributeSet import android.view.MotionEvent import android.view.View class ProgressButton : View { constructor(context: Context?, attrs: AttributeSet?) : super( context, attrs){ init(context!!, attrs!!) } constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context, attrs){ init(context!!, attrs!!) } private lateinit var fm: Paint.FontMetrics private var progress = 0 private var textColor: Int = Color.WHITE private var paint: Paint? = null private var textSize: Float = 10f private var foreground = 0 private var backgroundcolor = 0 private var text: String? = null private var max = 100 private val corner = 5 // 圆角的弧度 private var buttonClickListener: OnProgressButtonClickListener? = null private fun init( context: Context, attrs: AttributeSet ) { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressButton) backgroundcolor = typedArray.getInteger( R.styleable.ProgressButton_backgroundcolor, Color.parseColor("#C6C6C6") ) foreground = typedArray.getInteger( R.styleable.ProgressButton_foreground, Color.rgb(20, 131, 214) ) textColor = typedArray.getInteger( R.styleable.ProgressButton_textcolor, Color.WHITE ) max = typedArray.getInteger(R.styleable.ProgressButton_max, 100) progress = typedArray.getInteger(R.styleable.ProgressButton_progress, 0) text = typedArray.getString(R.styleable.ProgressButton_text) textSize = typedArray.getDimension(R.styleable.ProgressButton_textSize, 20f) typedArray.recycle() } @SuppressLint("DrawAllocation") override fun onDraw(canvas: Canvas) { super.onDraw(canvas) paint = Paint() paint!!.setAntiAlias(true) paint!!.setStrokeWidth(5f) /** * 绘制背景 */ var oval = RectF(0F, 0F, width.toFloat(), height.toFloat()) paint!!.setColor(this.backgroundcolor) canvas.drawRoundRect(oval, corner.toFloat(), corner.toFloat(), paint) /*** * 绘制进度值 */ paint!!.setColor(foreground) if (progress <= corner) { oval = RectF( 0F, (corner - progress).toFloat(), (width * progress / max).toFloat(), (height - corner + progress).toFloat() ) canvas.drawRoundRect(oval, progress.toFloat(), progress.toFloat(), paint) } else { oval = RectF( 0F, 0F, (width * progress / max).toFloat(), height.toFloat() ) canvas.drawRoundRect(oval, corner.toFloat(), corner.toFloat(), paint) } /*** * 绘制文本 */ if ("" == text || text == null) { return } paint!!.setTextSize(textSize) fm = paint!!.getFontMetrics() paint!!.setColor(textColor) val textCenterVerticalBaselineY = height / 2 - fm.descent + (fm.descent - fm.ascent) / 2 canvas.drawText( text, (measuredWidth - paint!!.measureText(text)) / 2, textCenterVerticalBaselineY, paint ) } /** * 设置最大值 * * @param max */ fun setMax(max: Int) { this.max = max } /** * 设置文本提示信息 * * @param text */ fun setText(text: String?) { this.text = text } /** * 设置进度条的颜色值 * * @param color */ fun setForeground(color: Int) { foreground = color } /** * 设置进度条的背景色 */ override fun setBackgroundColor(color: Int) { this.backgroundcolor = color } /*** * 设置文本的大小 */ fun setTextSize(size: Int) { textSize = size.toFloat() } /** * 设置文本的颜色值 * * @param color */ fun setTextColor(color: Int) { textColor = color } /** * 设置进度值 * * @param progress */ fun setProgress(progress: Int) { if (progress > max) { return } this.progress = progress //设置进度之后,要求UI强制进行重绘 postInvalidate() } fun getMax(): Int { return max } fun getProgress(): Int { return progress } @SuppressLint("ClickableViewAccessibility") override fun onTouchEvent(event: MotionEvent): Boolean { when (event.action) { MotionEvent.ACTION_UP -> buttonClickListener!!.onClickListener() else -> { } } return true } fun setOnProgressButtonClickListener(clickListener: OnProgressButtonClickListener) { buttonClickListener = clickListener } interface OnProgressButtonClickListener { fun onClickListener() } }
自定义属性attr
我们在Android的res–values下面创建一个attr.xml,名称起什么倒是无所谓

<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ProgressButton"> <attr name="backgroundcolor" format="color" /> <attr name="foreground" /> <attr name="textcolor" format="color" /> <attr name="max" /> <attr name="progress" /> <attr name="textSize" /> <attr name="text" format="string" /> </declare-styleable> </resources>
通过上面两步,我们的ProgressButton的自定义控件就实现了,接下来我们就看看怎么去使用。
ProgressButton使用

微卡智享
activity_main.xml
在主窗体的布局文件中可以直接就加入我们刚才已经生成的ProgressButton
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <dem.vac.progressbutton.ProgressButton android:layout_gravity="center" android:layout_width="100dp" android:layout_height="50dp" app:backgroundcolor="@color/colorLightSkyBlue" app:foreground="@color/colorRoyalBlue" app:textcolor="@color/colorWhite" app:text="点击开始" android:id="@+id/progressbtn" /> </LinearLayout>

MainActivity.kt
接下来看看我们主程序的使用代码
package dem.vac.progressbutton import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlin.concurrent.thread class MainActivity : AppCompatActivity() { lateinit var probtn: ProgressButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) probtn = findViewById(R.id.progressbtn) probtn.setOnProgressButtonClickListener(object : ProgressButton.OnProgressButtonClickListener { override fun onClickListener() { thread { for (i in 1..100) { probtn.setProgress(i) probtn.setText("当前$i") Thread.sleep(50) } } } }) } }

代码中我们直接就调用到ProgressButton,然后重写了onProgressButtonClickListerner事件,事件中我们开启了一个线程,做了一1到100的循环,调用到的效果就是我们文章开头的那个动图效果。