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

xiaoxiao2021-02-27  382

写动画的同事离职了,没办法,我只能接手他的部分工作 : ( 。 最近写了不少自定义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 }
转载请注明原文地址: https://www.6miu.com/read-1423.html

最新回复(0)