android录音的动画自定义View
程序员文章站
2022-04-25 17:41:09
...
引文
最近接了一下新需求,就像录音的按钮…
之前在微信小程序上也写过->小程序录音及其动画
去年在android上也实现过….下面是去年实现的时候的代码
大概这样
正文
首先View的绘制有几个过程,measure->layout->draw。如果本文的需求,高宽都是一定的,那么细节点就都在draw了。简单说有几个步骤:
-
onSizeChanged
初始化画笔,获取高宽等信息 -
onDraw
获取 canvas,进行绘制 -
postInvalidate()
数据有更新的时候触发重绘
canvas.draw 关注点主要是在纹理上,比如说圆形、方形,从哪个位置绘制到哪个位置
Paint.setShader 关注点在 色彩的渐变,颜色的遮罩
把之前android写过的代码放上来吧,也是一个笔记…
/*********************************************************************
* This file is part of seeyoutime project
* Created by aaa@qq.com on 2017/2/21.
* Copyright (c) 2017 XingDian Co.,Ltd. - All Rights Reserved
*********************************************************************/
/**
* 短视频录制界面的开始录制按钮,有如下特性:
* 1,放大
* 2,显示当前进度
*/
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)
}
}
}
values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<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.seeyoutime.ProgressRecordView
android:id="@+id/edit_video_record_btn"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="70dp"
app:barPressColor="@color/yellow.light"
app:barPressWidth="5dp"
app:bgColor="@color/white"
app:bgInnerColor="@color/yellow.light"
app:bgInnerWidth="90dp"
app:bgPressColor="@color/white"
app:bgWidth="100dp" />
mRecordBtn.setOnClickListener {}
mRecordBtn.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
mRecordBtnHint.visibility = View.INVISIBLE
(mRecordBtn.tag as? ValueAnimator)?.cancel()
mRecordBtn.tag = ObjectAnimator.ofInt(mRecordBtn.minProgress, mRecordBtn.maxProgress).apply {
duration = VideoControlView.SHORT_VIDEO_LENGTH
addUpdateListener { animation ->
mRecordBtn.pressing = true
mRecordBtn.progress = animation.animatedValue as Int
}
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
mRecordBtn.tag = null
mPlayerView?.stopRecord()
}
})
start()
}
mPlayerView?.record()
}
MotionEvent.ACTION_UP -> {
(mRecordBtn.tag as? ValueAnimator)?.cancel()
}
}
aaa@qq.com false
}
mRecordBtn.pressing = false
mRecordBtn.progress = 0
上一篇: 第五章(2)使用流-----映射
下一篇: html map热点链接图像映射
推荐阅读
-
Android自定义View仿微信LetterView效果
-
Android实现自定义圆角对话框Dialog的示例代码
-
Android编程实现自定义进度条颜色的方法
-
Android自定义view圆并随手指移动
-
Android开发使用自定义view实现ListView下拉的视差特效功能
-
Android开发自定义TextView省略号样式的方法
-
Android开发中自定义ProgressBar控件的方法示例
-
Android开发中获取View视图宽与高的常用方法小结
-
Android View 完美实现EditText 在软键盘上边的示例
-
Android编程实现自定义分享列表ACTION_SEND功能的方法