美文网首页
安卓仿华为天气圆弧进度条

安卓仿华为天气圆弧进度条

作者: 安卓呃 | 来源:发表于2018-11-27 17:36 被阅读0次
    Screenshot_20181127-172550_SimpleWar.jpg

    效果图如上
    圆弧比较好画,drawArc随便百度一下就行,注意画线的时候用了圆角线,看起来比较好看一点.
    代码如下
    自定义view

    private var mPaint = Paint()
        private var textPaint = Paint()
        private var maxValue = 100f
        private var minValue = 0f
        private val centerRect = Rect()
        private val minRect = Rect()
        private val maxRect = Rect()
        private var centerText = ""
            set(value) {
                field = value
                textPaint.getTextBounds(value, 0, value.length, centerRect)
            }
        var aimRatio = 0f
            set(value) {
                field = if (value > 1f)
                    1f
                else
                    value
                centerText = "${(field * (maxValue - minValue) + minValue).format()}"
                ObjectAnimator.ofFloat(this, "ratio", ratio, aimRatio).apply {
                    duration = 500
                    interpolator = DecelerateInterpolator()
                    addUpdateListener {
                        ratio = it.animatedValue.toString().toFloat()
                        invalidate()
                    }
                    start()
                }
            }
        var ratio = 0f
            private set
        var hOffset = 0
    
        init {
            mPaint.style = Paint.Style.STROKE
            //设置圆角线条
            mPaint.strokeCap = Paint.Cap.ROUND
            mPaint.strokeWidth = 20f
            textPaint.textSize = 28f
            textPaint.color = Color.WHITE
            val typedArray: TypedArray? = context.obtainStyledAttributes(attrs, R.styleable.CircleProgress)
            ratio = typedArray?.getFloat(R.styleable.CircleProgress_ratio, 0f) ?: 0f
            maxValue = typedArray?.getFloat(R.styleable.CircleProgress_maxValue, 100f) ?: 100f
            minValue = typedArray?.getFloat(R.styleable.CircleProgress_minValue, 0f) ?: 0f
            typedArray?.recycle()
            centerText = "${(ratio * (maxValue - minValue) + minValue).format()}"
            textPaint.getTextBounds(centerText, 0, centerText.length, centerRect)
            textPaint.getTextBounds(minValue.toString(), 0, minValue.toString().length, minRect)
            textPaint.getTextBounds(maxValue.toString(), 0, minValue.toString().length, maxRect)
            //预留底部文字高度
            hOffset = centerRect.bottom - centerRect.top
        }
    
        override fun onDraw(canvas: Canvas) {
            //进度条背景
            mPaint.color = context.resources.getColor(R.color.bg_gray)
            canvas.drawArc(paddingStart + mPaint.strokeWidth / 2f, paddingTop + mPaint.strokeWidth / 2f, measuredWidth.toFloat() - paddingEnd - mPaint.strokeWidth / 2f,
                    measuredHeight.toFloat() - hOffset - paddingBottom - mPaint.strokeWidth / 2f, 115f, 310f, false, mPaint)
            //进度条
            mPaint.color = context.resources.getColor(R.color.btn_blue)
            canvas.drawArc(paddingStart + mPaint.strokeWidth / 2f, paddingTop + mPaint.strokeWidth / 2f, measuredWidth.toFloat() - paddingEnd - mPaint.strokeWidth / 2f,
                    measuredHeight.toFloat() - hOffset - paddingBottom - mPaint.strokeWidth / 2f, 115f, 310f * ratio, false, mPaint)
            //中心文字
            canvas.drawText(centerText, (measuredWidth - paddingStart - paddingEnd - centerRect.right + centerRect.left) / 2f + paddingStart,
                    (measuredHeight - hOffset - paddingTop - paddingBottom + centerRect.bottom - centerRect.top) / 2f + paddingTop, textPaint)
            //左下角文字
            canvas.drawText(minValue.toString(), (measuredWidth - paddingStart - paddingEnd) * (1f - Math.sin(Math.toRadians(25.0)).toFloat()) / 2f + 5f + paddingStart - minRect.right / 2f + minRect.left / 2f,
                    measuredHeight - (measuredWidth - paddingStart - paddingEnd) * (1f - Math.cos(Math.toRadians(25.0)).toFloat()) / 4f - paddingBottom, textPaint)
            //右下角文字
            canvas.drawText(maxValue.toString(), (measuredWidth - paddingStart - paddingEnd) * (1f + Math.sin(Math.toRadians(25.0)).toFloat()) / 2f - 5f + paddingStart - maxRect.right / 2f + maxRect.left / 2f,
                    measuredHeight - (measuredWidth - paddingStart - paddingEnd) * (1f - Math.cos(Math.toRadians(25.0)).toFloat()) / 4f - paddingBottom, textPaint)
        }
    
    
        override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
            var w = MeasureSpec.getSize(widthMeasureSpec)
            val wMode = MeasureSpec.getMode(widthMeasureSpec)
            if (wMode == MeasureSpec.AT_MOST || wMode == MeasureSpec.UNSPECIFIED) {
                w = 400
            }
            setMeasuredDimension(w, w + hOffset)
        }
    

    xml

    <com.view.CircleProgress
                android:id="@+id/cp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:padding="@dimen/dimen_size_24"
                app:ratio="0.6"
                app:minValue="20"
                app:maxValue="120"
                android:background="@color/colorPrimaryDark"/>
    
            <EditText
                android:id="@+id/et"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="numberDecimal"
                android:layout_below="@+id/cp" />
    
            <Button
                android:id="@+id/btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/et"
                android:text="sure"/>
    

    activity

     mBinding.btn.setOnClickListener {
                if(mBinding.et.text.toString().isNotEmpty())
                mBinding.cp.aimRatio = mBinding.et.text.toString().toFloat()
            }
    

    中间的文字好定位点,下边两个文字要用到三角函数相关的东西,大家可以自己画图算算,不一定非要按我的来.

    如有问题或不足之处,欢迎批评指正

    相关文章

      网友评论

          本文标题:安卓仿华为天气圆弧进度条

          本文链接:https://www.haomeiwen.com/subject/ajmjzftx.html