一、demo简介

1.效果展示如下图,我截了三个瞬间,但其实这是一个连续的动画,就是这个大圆不停地吞下小圆。

2.这个动画可以拆分为两部分,首先是大圆张嘴闭嘴的动画,相当于画一个圆弧,规定一下它的角度就好。小圆就是一个从右向左移动的动画。然后不停地刷新界面,让动画的持续时间为永恒,这样就会有一个持续的动态效果。

二、分析贪吃动画的尺寸比例

1.在制作动画之前,我们要先建一个模型,来确定一下大圆和小圆的比例。这个比例是自己设置的,可以自行修改。下图是画布的宽度大于高度的情况。

R = minHeight /6

Cx = (width - minwidth)/2 3R

Cy = height/2

还有一种是画布宽度小于高度的情况,如下图所示:这个时候

6R 0.5R 2R = minwidth。 R = minwidth /8.5

Cx = 3R

Cy =height/2

2.确定了大圆圆心坐标之后,小圆的圆心坐标也可以知道了。

三、画圆

1.先创建一个类继承自view,并实现其对应的构造方法

class MouseLoadingView : View {
    constructor(context: Context):super(context){}
    constructor(context: Context,attrs:AttributeSet?):super(context,attrs){}
    constructor(context: Context,attrs:AttributeSet?,style:Int):super(context,attrs,style){}
}

2.定义一下大圆(嘴)的半径(3R),小圆的半径(R)以及两圆之间的间距(0.5R),还有嘴的圆心坐标

 //嘴的半径
    private var mouseRadius = 0f
    //小圆的半径
    private var ballRadius = 0f
    //嘴和小球的间距
    private var space = 0f
 //嘴的圆心
    private var cx = 0f
    private var cy = 0f

3. 在onSizeChanged方法里面计算尺寸。

 override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
       if(measuredWidth>=measuredHeight){
           ballRadius= measuredHeight/6f
            cx = (measuredWidth-8.5f*ballRadius)/2   3*ballRadius
        }else{
           ballRadius= measuredWidth/8.5f
            cx = 3*ballRadius.toFloat()
        }
        mouseRadius = 3*ballRadius
        space = ballRadius/2f

        cy = measuredHeight/2f
    }

4.提供一个画笔

//画笔
    private val mPaint = Paint().apply {
        style = Paint.Style.FILL
        color = context.resources.getColor(R.color.colorAccent,null)
    }

5.在onDraw方法里面画一个圆

override fun onDraw(canvas: Canvas?) {
 canvas?.drawCircle(cx,cy,mouseRadius,mPaint)
}

6.在xml文件里面添加这个自定义类

  <com.example.loadinganim.MouseLoadingView
        android:id="@ id/loadingView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.11" />

7.如果用上面的方法来画圆,会出现一些bug,如下图所示

这是因为,当宽度大于高度时,R= height/6。如果R过小,那么圆心的坐标就会偏左,那么就会有一部份圆出界。为了避免这种情况发生,无论什么情况下,都把R设置为最小的那个/8.5。

8.重新计算一下半径

override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        //计算尺寸
        //小球的半径
       ( Math.min(measuredHeight,measuredWidth)/8.5f ).also {r->
            ballRadius = r
            //嘴的半径
            mouseRadius = 3*r
            //嘴和小球的间距
            space = r/2

            //嘴的圆心
            cx = ((measuredWidth- 8.5*r)/2   3*r).toFloat()
            cy = measuredHeight/2f
        }
    }

四、实现张嘴闭嘴动画

1.张嘴相当于画了一个弧,画弧需要确定一个矩形区域——即大圆所在的矩形。还需要设置一个角度,也就是弧度。绘制出来如下图所示。

override fun onDraw(canvas: Canvas?) {
 canvas?.drawArc(
            cx-mouseRadius,
            cy-mouseRadius,
            cx mouseRadius,
            cy mouseRadius,
           45f,270f,true,mPaint
        )
}

image.png

2.这是一个静态的过程,想让它变成动态的话,只需要一直修改嘴张开的角度即可。所以我们定义一个动画因子,作为弧度

 //嘴张开的角度 - >张嘴的动画因子
     private var mouseAngle = 0f

3.然后在onDraw方法里面,把死数据改为我们动画因子即可。

canvas?.drawArc(
           cx-mouseRadius,
           cy-mouseRadius,
           cx mouseRadius,
           cy mouseRadius,
           mouseAngle,360-2*mouseAngle,true,mPaint
       )

4.添加两个按钮,来显示动画和暂停动画。当点击按钮时,实现对应的点击事件。

5.所以在MouseLoadingView类里面提供几个方法给外部调用

    }
    //提供给外部使用
    //显示动画
    fun show(){
     createAnimator()
        start()
    }
    //隐藏动画
    fun hide(){
      stop()
    }

6.createAnimator()是创建动画的函数。从0-45-0的是动画因子的变化,监听一下动画执行的过程,不断刷新动画因子的数值,然后刷新界面。

private fun createAnimator() {
    ValueAnimator.ofFloat(0f, 45f, 0f).apply {
            duration = 650
            repeatCount = ValueAnimator.INFINITE
            addUpdateListener {
                mouseAngle = it.animatedValue as Float
                //刷新界面
                invalidate()
            }
            animators.add(this)
        }
}

7.因为动画效果有很多,所以我们要用一个数组来保存所有的动画

  //保存所有的动画对象
    private var animators = mutableListOf<ValueAnimator>()

8.添加几个启动和结束动画的方法

//启动动画
    private fun start(){
        for(anim in animators){
            anim.start()
        }
    }
//暂停动画
    private fun stop(){
    for(anim in animators){
        anim.end()
    }

五、小球移动动画

1.创建一个小球,然后让它从右边向左边移动即可。小球圆心的x坐标在不断改变,y坐标与大圆一样。所以我们要给小球设置一个移动的动画因子。

//小球移动的动画因子
    private var ballTranslateX = 0f

2.然后在onDraw()方法里面绘制小球

//绘制小球
canvas?.drawCircle(cx ballTranslateX,cy,ballRadius,mPaint)

3.之后,在createAnimator()方法里面添加小球的动画。让小球移动的距离从4.5R到0,也就是直到小圆与大圆重合。

 ValueAnimator.ofFloat(4.5f*ballRadius, 0f).apply {
            duration = 650
            repeatCount = ValueAnimator.INFINITE
            addUpdateListener {
                ballTranslateX = it.animatedValue as Float
                //刷新界面
                invalidate()
            }
            animators.add(this)
        }

4.在MainActivity里面添加按钮的点击事件

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        startBtn.setOnClickListener{
            loadingView.show()
            pauseView.show()
        }

        stopBtn.setOnClickListener {
            loadingView.hide()
            pauseView.hide()
        }
    }
}

差不多就这些内容。自定义加载动画的难点,主要在于找到动画因子。

以上就是Android开发之自定义加载动画详解的详细内容,更多关于Android加载动画的资料请关注Devmax其它相关文章!

Android开发之自定义加载动画详解的更多相关文章

  1. Canvas实现贝赛尔曲线轨迹动画的示例代码

    这篇文章主要介绍了Canvas实现贝赛尔曲线轨迹动画的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. HTML5 直播疯狂点赞动画实现代码 附源码

    为了烘托直播间的氛围,直播相对于普通视频或者文本内容,点赞动作通常无限次,引导用户疯狂点赞,今天小编给大家分享HTML5 直播疯狂点赞动画实现代码 附源码,感兴趣的朋友一起看看吧

  3. CSS中实现动画效果-附案例

    这篇文章主要介绍了 CSS中实现动画效果并附上案例代码及实现效果,就是CSS动画样式处理,动画声明需要使用@keyframes name,后面的name是人为定义的动画名称,下面我们来看看文章的具体实现内容吧,需要的小伙伴可以参考一下

  4. 基于canvas的骨骼动画的示例代码

    这篇文章主要介绍了基于canvas的骨骼动画的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. html5如何在Canvas中实现自定义路径动画示例

    本篇文章主要介绍了html5如何在Canvas中实现自定义路径动画示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  6. html5 canvas合成海报所遇问题及解决方案总结

    这篇文章主要介绍了html5 canvas合成海报所遇问题及解决方案总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. 基于HTML5+Webkit实现树叶飘落动画

    本文给大家分享一段实例代码给大家介绍基于HTML5+Webkit实现树叶飘落动画效果,需要的朋友参考下吧

  8. Html5页面内使用JSON动画的实现

    这篇文章主要介绍了Html5页面内使用JSON动画的实现的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. html5实现图片转圈的动画效果——让页面动起来

    这篇文章主要介绍了html5实现图片转圈的动画效果——让页面动起来的相关资料,需要的朋友可以参考下

  10. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部