自定义View 绘制进度按钮(ProgressButton)

来源:互联网 发布:个人it外包平台 编辑:程序博客网 时间:2024/05/22 11:38

写动画的同事离职了,没办法,我只能接手他的部分工作 : ( 。
最近写了不少自定义view。

这个的效果是

1,没按下时是两个同心圆的按钮
2,按下时,同心圆白色背景放大
3,按下后开始根据时间做进度动画
4,进度动画是一个随着时间增加而增加扇角的圆环

代码足够短,就不补描述(图)了

core code

class ProgressRecordView : View {    private var diameter = 0F    private var barPressWidth = 0F    private var barPressColor = 0xFFFFFFFF.toInt()    private var bgPressColor = 0xFFFFFFFF.toInt()    private var bgWidth = diameter    private var bgInnerWidth = 0F    private var bgInnerColor = 0xFFFFFFFF.toInt()    private var bgColor = 0xFFFFFFFF.toInt()    private val pressPaint = Paint()    private val pressBgPaint = Paint()    private val pressBarBounds = RectF()    private val bgPaint = Paint()    private val bgInnerPaint = Paint()    val minProgress = 0    val maxProgress = 360    var pressing = false    var progress = 0        set(value) {            field = value            postInvalidate()        }    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 array = context.obtainStyledAttributes(attrs, R.styleable.ProgressRecordView)        //宽度都是指直径        barPressWidth = array.getDimension(R.styleable.ProgressRecordView_barPressWidth, barPressWidth)        bgInnerWidth = array.getDimension(R.styleable.ProgressRecordView_bgInnerWidth, bgInnerWidth)        bgWidth = array.getDimension(R.styleable.ProgressRecordView_bgWidth, bgWidth)        barPressColor = array.getColor(R.styleable.ProgressRecordView_barPressColor, barPressColor)        bgPressColor = array.getColor(R.styleable.ProgressRecordView_bgPressColor, bgPressColor)        bgInnerColor = array.getColor(R.styleable.ProgressRecordView_bgInnerColor, bgInnerColor)        bgColor = array.getColor(R.styleable.ProgressRecordView_bgColor, bgColor)        array.recycle()    }    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {        super.onMeasure(widthMeasureSpec, widthMeasureSpec)        //以宽度为准的正方形    }    override fun onSizeChanged(w: Int, h: Int, oldWidth: Int, oldHeight: Int) {        super.onSizeChanged(w, h, oldWidth, oldHeight)        diameter = w.toFloat()        //set-up bounds        pressBarBounds.set(barPressWidth / 2,                barPressWidth / 2,                width - barPressWidth / 2,                height - barPressWidth / 2)        //set-up paint        pressPaint.color = barPressColor        pressPaint.isAntiAlias = true        pressPaint.style = Paint.Style.STROKE        pressPaint.strokeWidth = barPressWidth        pressBgPaint.color = bgPressColor        pressBgPaint.isAntiAlias = true        pressBgPaint.style = Paint.Style.FILL        bgPaint.color = bgColor        bgPaint.isAntiAlias = true        bgPaint.style = Paint.Style.FILL        bgInnerPaint.color = bgInnerColor        bgInnerPaint.isAntiAlias = true        bgInnerPaint.style = Paint.Style.FILL    }    override fun onDraw(canvas: Canvas?) {        super.onDraw(canvas)        if (pressing) {            canvas?.drawCircle(diameter / 2, diameter / 2, diameter / 2 - 1, pressBgPaint)            canvas?.drawArc(pressBarBounds, -90F, progress.toFloat(), false, pressPaint)        } else {            canvas?.drawCircle(diameter / 2, diameter / 2, bgWidth / 2, bgPaint)            canvas?.drawCircle(diameter / 2, diameter / 2, bgInnerWidth / 2, bgInnerPaint)        }    }}

res value attrs.xml

<resources><declare-styleable name="ProgressRecordView">    <attr name="barPressWidth" format="dimension" />    <attr name="bgInnerWidth" format="dimension" />    <attr name="bgWidth" format="dimension"/>    <attr name="barPressColor" format="color" />    <attr name="bgPressColor" format="color" />    <attr name="bgInnerColor" format="color" />    <attr name="bgColor" format="color" /></declare-styleable></resources>

调用

<org.yeshen.demo.ProgressRecordView    android:id="@+id/edit_video_record_btn"    android:layout_width="70dp"    android:layout_height="70dp"    android:layout_gravity="center_horizontal"    android:layout_marginTop="80dp"    app:barPressColor="@color/yellow.light"    app:barPressWidth="5dp"    app:bgColor="@color/white"    app:bgInnerColor="@color/yellow.light"    app:bgInnerWidth="50dp"    app:bgPressColor="@color/white"    app:bgWidth="60dp" />mRecordBtn.setOnClickListener {}mRecordBtn.setOnTouchListener { _, event ->    when (event.action) {        MotionEvent.ACTION_DOWN -> {       //TODO do something            (mRecordBtn.tag as? ValueAnimator)?.cancel()            mRecordBtn.tag = ObjectAnimator.ofInt(mRecordBtn.minProgress, mRecordBtn.maxProgress).apply {                duration = VideoControlView.SHORT_VIDEO_LENGTH//VideoControlView.SHORT_VIDEO_LENGTH = 10000L                addUpdateListener { animation ->                      mRecordBtn.pressing = true                    mRecordBtn.progress = animation.animatedValue as Int                }                addListener(object : AnimatorListenerAdapter() {                    override fun onAnimationEnd(animation: Animator) {                        mRecordBtn.tag = null                        //TODO do something                        Lg.e("onAnimationEnd stopRecord")                    }                })                start()            }        }        MotionEvent.ACTION_UP -> {            (mRecordBtn.tag as? ValueAnimator)?.cancel()        }    }    return@setOnTouchListener false}
0 0