欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android開發(fā)Kotlin實(shí)現(xiàn)圓弧計(jì)步器示例詳解

 更新時(shí)間:2022年06月27日 09:04:22   作者:as_pixar  
這篇文章主要為大家介紹了Android開發(fā)Kotlin繪制圓弧計(jì)步器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

效果圖

定義控件的樣式

看完效果后,我們先定義控件的樣式

<!-- 自定義View的名字 StepView -->
        <!-- name 屬性名稱  format 格式
        string 文字    color 顏色    dimension 字體大小
        integer 數(shù)字   reference 資源或者顏色
        -->
<declare-styleable name="StepView">
        <attr name="borderWidth" format="dimension" />
        <attr name="outColor" format="color" />
        <attr name="innerColor" format="color" />
        <attr name="unit" format="string" />
        <attr name="currentStep" format="integer" />
        <attr name="maxStep" format="integer" />
    </declare-styleable>

自定義StepView

接下來我們自定義一個(gè)StepView(記步的View)

package cn.wwj.customview.widget
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.util.TypedValue
import android.view.animation.AccelerateInterpolator
import androidx.appcompat.widget.AppCompatTextView
import cn.wwj.customview.R
class StepView : AppCompatTextView {
    /**
     * 當(dāng)前走了多少步
     */
    private var mCurrentStep: Int = 0
    /**
     * 最大走多少步,比如兩萬步 20000步
     * 默認(rèn)100步,有個(gè)成語(yǔ)50步笑100步
     */
    private var mMaxStep: Int = 100
    /**
     * 單位:步 %等
     */
    private var mUnit: String?
    /**
     * 設(shè)置圓弧的邊框線寬度
     */
    private var mBorderWidth: Float = dp2px(6F)
    /**
     * 設(shè)置外部圓弧的顏色
     */
    private var mOuterColor: Int = resources.getColor(android.R.color.holo_blue_light)
    /**
     * 設(shè)置內(nèi)部圓弧的顏色
     */
    private var mInnerColor: Int = resources.getColor(android.R.color.holo_red_light)
    /**
     * 圓弧畫筆
     */
    private var mArcPaint: Paint = Paint()
    /**
     * 文本畫筆,用于繪畫走了多少步
     */
    private var mTextPaint: Paint = Paint()
    /**
     * 日志過濾標(biāo)簽
     */
    private val TAG = javaClass.simpleName
    /**
     * 圓弧起始角度
     */
    private var mStartAngle = 135F
    /**
     * 圓弧從起始角度開始,掃描過的角度
     */
    private var mSweepAngle = mStartAngle * 2
    /**
     *  比如用于獲取一個(gè)圓弧的矩形,onDraw()方法會(huì)調(diào)用多次,不必每次都創(chuàng)建Rect()對(duì)象
     */
    private val mArcRect = RectF()
    /**
     *  比如用于獲取文字的大小,onDraw()方法會(huì)調(diào)用多次,不必每次都創(chuàng)建Rect()對(duì)象
     *  用同一個(gè)對(duì)象即可
     */
    private val mTextRect = Rect()
    /**
     * 值動(dòng)畫師
     */
    private var valueAnimator: ValueAnimator? = null
    /**
     * 最大進(jìn)度
     */
    private val MAX_PROGRESS = 100F
    constructor(context: Context)
            : this(context, null)
    constructor(context: Context, attrs: AttributeSet?)
            : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
            : super(context, attrs, defStyleAttr) {
        val appearance = context.obtainStyledAttributes(attrs, R.styleable.StepView)
        mBorderWidth = appearance.getDimension(R.styleable.StepView_borderWidth, mBorderWidth)
        mOuterColor = appearance.getColor(R.styleable.StepView_outColor, mOuterColor)
        mInnerColor = appearance.getColor(R.styleable.StepView_innerColor, mInnerColor)
        mUnit = appearance.getString(R.styleable.StepView_unit)
        mCurrentStep = appearance.getInt(R.styleable.StepView_currentStep, 0)
        mMaxStep = appearance.getInt(R.styleable.StepView_maxStep, mMaxStep)
        appearance.recycle()
        setPaint()
    }
    /**
     * 設(shè)置 圓弧畫筆用于繪制圓弧 和 文本畫筆,用于繪畫走了多少步
     */
    private fun setPaint() {
        // 畫筆的顏色
        mArcPaint.color = mOuterColor
        // 抗抖動(dòng)
        mArcPaint.isDither = true
        // 抗鋸齒
        mArcPaint.isAntiAlias = true
        // 畫筆的樣式描邊,筆劃突出為半圓
        mArcPaint.style = Paint.Style.STROKE
        // 設(shè)置描邊的線帽樣式
        mArcPaint.strokeCap = Paint.Cap.ROUND
        // 設(shè)置描邊的寬度
        mArcPaint.strokeWidth = mBorderWidth
        // 畫筆的顏色
        mTextPaint.color = currentTextColor
        // 抗抖動(dòng)
        mTextPaint.isDither = true
        // 抗鋸齒
        mTextPaint.isAntiAlias = true
        // 畫筆的樣式描邊,筆劃突出為半圓
        mTextPaint.style = Paint.Style.FILL
        // 設(shè)置描邊的線帽樣式
        mTextPaint.strokeCap = Paint.Cap.ROUND
        // 設(shè)置文本大小
        mTextPaint.textSize = textSize
    }
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        /**
         * 獲取控件的寬高
         */
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)
        /**
         * 如果寬度大于高度,取高度
         * 否則取寬度
         */
        val result = if (widthSize > heightSize) {
            heightSize
        } else {
            widthSize
        }
        /**
         * 設(shè)置控件的寬高
         */
        setMeasuredDimension(result, result)
    }
    override fun onDraw(canvas: Canvas?) {
        // 將矩形設(shè)置為 (0,0,0,0)
        mArcRect.setEmpty()
        mTextRect.setEmpty()
        // 圓弧矩形左邊距,頂邊距,右邊距,底邊距
        val left = mBorderWidth / 2
        val top = mBorderWidth / 2
        val right = width - mBorderWidth / 2
        val bottom = height - mBorderWidth / 2
        mArcRect.set(left, top, right, bottom)
        // 繪制外部圓弧
        mArcPaint.color = mOuterColor
        canvas?.drawArc(mArcRect, mStartAngle, mSweepAngle, false, mArcPaint)
        // 繪制內(nèi)部部圓弧
        mArcPaint.color = mInnerColor
        val sweepAngle = mCurrentStep * 1F / mMaxStep * mSweepAngle
        canvas?.drawArc(mArcRect, mStartAngle, sweepAngle, false, mArcPaint)
        val stepText = if (mUnit != null) {
            "$mCurrentStep $mUnit"
        } else {
            mCurrentStep.toString()
        }
        // 獲取文本的寬高
        mTextPaint.getTextBounds(stepText, 0, stepText.length, mTextRect)
        val textX = width / 2F - mTextRect.width() / 2
        val textY = height / 2F + getBaseline(mTextPaint)
        // 繪制文本,第二個(gè)參數(shù)文本的起始索引,第三個(gè)參數(shù)要繪制的文字長(zhǎng)度
        // 開始繪制文字的x 坐標(biāo) y 坐標(biāo)
        canvas?.drawText(stepText, 0, stepText.length, textX, textY, mTextPaint)
    }
    /**
     * @param progress 進(jìn)入0-100 之間
     * @param duration 動(dòng)畫時(shí)長(zhǎng),默認(rèn) 350毫秒
     */
    fun setProgress(progress: Int, duration: Long = 350) {
        valueAnimator?.cancel()
        valueAnimator = null
        val step = (progress / MAX_PROGRESS * mMaxStep).toInt()
        valueAnimator = ValueAnimator.ofInt(mCurrentStep, step.coerceAtMost(mMaxStep))
        valueAnimator?.duration = duration
        valueAnimator?.interpolator = AccelerateInterpolator()
        valueAnimator?.addUpdateListener {
            mCurrentStep = it.animatedValue as Int
            Log.d(TAG, "------$mCurrentStep")
            invalidate()
        }
        valueAnimator?.startDelay = 10
        valueAnimator?.start()
    }
    /**
     * @param maxStep  最多走多少步,比如2000步
     * @param duration 默認(rèn)動(dòng)畫時(shí)長(zhǎng)200
     */
    fun setMaxStep(maxStep: Int, duration: Long = 0) {
        mMaxStep = maxStep
        val progress = (mCurrentStep * 1F / mMaxStep * 100).toInt()
        setProgress(progress, duration)
    }
    /**
     * @param currentStep 當(dāng)前走了多少步
     * @param duration 默認(rèn)動(dòng)畫時(shí)長(zhǎng)200
     */
    fun setCurrentStep(currentStep: Int, duration: Long = 200) {
        mCurrentStep = currentStep
        val progress = (mCurrentStep * 1F / mMaxStep * 100).toInt()
        setProgress(progress, duration)
    }
    /**
     * 視圖從窗口分離時(shí)
     */
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        valueAnimator?.cancel()
        valueAnimator = null
    }
    private fun dp2px(value: Float): Float {
        return TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, value, resources.displayMetrics
        )
    }
    /**
     * 計(jì)算繪制文字時(shí)的基線到中軸線的距離
     * @param paint 畫筆
     * @return 返回基線的距離
     */
    private fun getBaseline(paint: Paint): Float {
        val fontMetrics: Paint.FontMetrics = paint.fontMetrics
        return (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
    }
}

繪制圓弧是是從3點(diǎn)中開始,它位于0度。比如我們可以試試?yán)L制0到90度的圓弧,多試試幾次,你很快就能明白了額

繪制文本坐標(biāo)

繪制文本橫坐標(biāo)是控件寬度的一半減去字體寬度的一半,繪制文本的縱坐標(biāo)是控件高度的一半加上文字的基線。

文字基線我們看個(gè)圖清楚了

Android獲取中線到基線距離

Android獲取中線到基線距離的代碼,實(shí)際獲取到的Ascent是負(fù)數(shù)

/**
     * 計(jì)算繪制文字時(shí)的基線到中軸線的距離
     * @param paint 畫筆
     * @return 返回基線的距離
     */
    private fun getBaseline(paint: Paint): Float {
        val fontMetrics: Paint.FontMetrics = paint.fontMetrics
        return (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom
    }

項(xiàng)目地址 :https://github.com/githubwwj/MyAndroid

以上就是Android開發(fā)Kotlin繪制圓弧計(jì)步器示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android Kotlin繪制圓弧計(jì)步器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解析JavaSE的繼承和多態(tài)

    解析JavaSE的繼承和多態(tài)

    這篇文章主要為大家詳細(xì)介紹了JavaSE的繼承和多態(tài),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • mybatis如何批量添加一對(duì)多中間表

    mybatis如何批量添加一對(duì)多中間表

    這篇文章主要介紹了mybatis如何批量添加一對(duì)多中間表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • maven-surefire-plugin總結(jié)示例詳解

    maven-surefire-plugin總結(jié)示例詳解

    這篇文章主要介紹了maven-surefire-plugin總結(jié),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • springboot整合spring-retry的實(shí)現(xiàn)示例

    springboot整合spring-retry的實(shí)現(xiàn)示例

    本文將結(jié)合實(shí)例代碼,介紹springboot整合spring-retry的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • Java PriorityQueue優(yōu)點(diǎn)和缺點(diǎn)面試精講

    Java PriorityQueue優(yōu)點(diǎn)和缺點(diǎn)面試精講

    這篇文章主要為大家介紹了Java面試中PriorityQueue的優(yōu)點(diǎn)和缺點(diǎn)及使用注意詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • java使用smortupload上傳和下載文件

    java使用smortupload上傳和下載文件

    這篇文章主要介紹了java使用smortupload上傳和下載文件實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • WebDriver中實(shí)現(xiàn)對(duì)特定的Web區(qū)域截圖方法

    WebDriver中實(shí)現(xiàn)對(duì)特定的Web區(qū)域截圖方法

    這篇文章主要介紹了WebDriver中實(shí)現(xiàn)對(duì)特定的Web區(qū)域截圖方法,本文直接給出實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • 如何用好Java枚舉讓你的工作效率飛起來

    如何用好Java枚舉讓你的工作效率飛起來

    在JDK1.5之前沒有枚舉類型,那時(shí)候一般用接口常量來替代,而使用Java枚舉類型enum可以更貼近地表示這種常量,下面這篇文章主要給大家介紹了關(guān)于如何用好Java枚舉讓你的工作效率飛起來的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • SpringSecurity 默認(rèn)表單登錄頁(yè)展示流程源碼

    SpringSecurity 默認(rèn)表單登錄頁(yè)展示流程源碼

    本篇主要講解 SpringSecurity提供的默認(rèn)表單登錄頁(yè) 它是如何展示流程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-01-01
  • Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法

    Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法

    本篇文章主要介紹了Spring Boot RestTemplate提交表單數(shù)據(jù)的三種方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03

最新評(píng)論