android小动画:不断扩散的圆点
程序员文章站
2022-07-03 19:36:54
效果图(ps: 其实就两个半径和透明度一起变化的小圆, 本项目中用来指示指尖位置)实现原理监听点击的位置,在父布局中动态增加 自定义的动画view代码实现(1)activity点击监听及添加view...
效果图
(ps: 其实就两个半径和透明度一起变化的小圆, 本项目中用来指示指尖位置)
实现原理
监听点击的位置,在父布局中动态增加 自定义的动画view
代码实现
(1)activity
点击监听及添加view
// 触屏点击位置 private var pointx: int = 0 private var pointy: int = 0 private var circleview: spreadcircleview?= null // 触摸点击 override fun ontouchevent(event: motionevent?): boolean { when (event!!.action) { motionevent.action_down -> { pointx = event.x.toint() pointy = event.y.toint() } motionevent.action_move -> { } motionevent.action_up ->{ addpointcircle() } else -> { } } return true }
/** * 添加自动扩散的圆点 view */ fun addpointcircle(){ if(circleview == null){ circleview = spreadcircleview(this); circleview?.let{ lifecycle.addobserver(it) } } binding.rootlayout.removeview(circleview) circleview?.let{ // 宽度和高度相同 val width = it.maxradius.toint() * 2 var lp = framelayout.layoutparams(width, width ) lp.marginstart = pointx - width/2 lp.topmargin = pointy - width/2 binding.rootlayout.addview(it, lp) it.startanimation() } }
(2)圆点view
实现(属性动画,根据动画进度来确定圆的当前半径,利用lifecycleobserver
绑定周期)
/** * created by liming on 2021/9/1 15:36 * 不断扩散的小圆, 用于显示指尖位置 */ class spreadcircleview : view, lifecycleobserver { private var paint: paint = paint() // 圆圈最大半径 val maxradius = 25.topx() // 圆圈中心点 var centerx:int = 0 var centery:int = 0 private var animator : objectanimator? = null // 是否已开始绘制第二个圆 var hasdrawcicle2 = false // 动画进度 private var progress = 0f set(value){ field = value // 刷新界面 invalidate() } constructor(context: context?) : super(context) constructor(context: context?, attrs: attributeset?) : super(context, attrs) constructor(context: context?, attrs: attributeset?, defstyleattr: int) : super(context, attrs, defstyleattr) init{ paint.style = paint.style.fill paint.color = contextcompat.getcolor(context, r.color.rect_orange) // #ffa200 paint.strokewidth = 3.topx() paint.isantialias = true // 防锯齿 } override fun onsizechanged(w: int, h: int, oldw: int, oldh: int) { super.onsizechanged(w, h, oldw, oldh) //圆心位置 centerx = w / 2; centery = h / 2; } override fun draw(canvas: canvas?) { super.draw(canvas) // 第一个圆 drawcircle(canvas, progress) // 第二个圆 if(hasdrawcicle2 || progress > 0.5f ){ // 第一个圆的进度第一次达到 0.5 时,开始绘制第二个圆, hasdrawcicle2 = true var progress2 = progress + 0.5f if(progress2 > 1){ progress2 = progress2 - 1 } drawcircle(canvas, progress2) } } /** * 根据进度绘制 半径和透明度变化的圆 */ fun drawcircle(canvas: canvas?, animprogress: float){ // 透明度 0 - 255 var alpha = 255 * (1 - animprogress) paint.alpha = alpha.toint() var radius = maxradius * animprogress // 绘制圆 canvas?.drawcircle(centerx.tofloat(), centery.tofloat(), radius, paint ) } private fun getanimator(): objectanimator?{ if(animator == null){ animator = objectanimator.offloat(this, "progress", 0f, 0.99f) animator?.duration = 1500 animator?.repeatcount = -1 //-1代表无限循环 animator?.interpolator = linearinterpolator() } return animator } fun startanimation() { // 开始动画 getanimator()?.start() hasdrawcicle2 = false } @onlifecycleevent(lifecycle.event.on_resume) fun resume() { // 开始动画 animator?.start() } @onlifecycleevent(lifecycle.event.on_pause) fun pause() { animator?.pause() } @onlifecycleevent(lifecycle.event.on_destroy) fun destory() { // 清除动画,避免内存泄漏, animator?.cancel() clearanimation() } }
补充一个用到的扩展函数
fun int.topx(): float{ val resources = resources.getsystem() return typedvalue.applydimension( typedvalue.complex_unit_dip, this.tofloat(), resources.displaymetrics ) }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。