前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >学习|Android中实现进度条按钮功能(kotlin)

学习|Android中实现进度条按钮功能(kotlin)

作者头像
Vaccae
发布2019-12-11 15:22:11
1.6K0
发布2019-12-11 15:22:11
举报
文章被收录于专栏:微卡智享微卡智享

本文长度为1029,预计阅读4分钟

Android中实现按钮进度条

前面几章做了检测TTS及怎么样进度条下载的文章,原想结合几个知识点做一个实战操作,模仿应用宝等手机助手的那种列表下载方式,计划中发现有一环是需要实现个一按钮进度条的方式,看了看以前没有相关的东西,那这篇我们就在看看Android怎么实现按钮进度条的功能。

实现效果

实现思路

要实现ProgressBar加上Button的方式,我们需要自定义类继承自View

然后在进度条滚动的时候进行样式布局的重画

创建xml的自定义属性和点击的接口监听事件

实现按钮进度条,并重新按钮的事件

划重点

我这里实现的是一个简单的方式,可以在这个基础上加上自己的一些新的设计,比如说加载进度条时的颜色和背景色重设,按钮在不同状态下的不同颜色,进度条中状态的监听等方法实现。

代码演示

ProgressButton

代码语言:javascript
复制
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,名称起什么倒是无所谓

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<?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

接下来看看我们主程序的使用代码

代码语言:javascript
复制
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的循环,调用到的效果就是我们文章开头的那个动图效果。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微卡智享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档