当前位置: 移动技术网 > 移动技术>移动开发>Android > kotlin的自定义动画

kotlin的自定义动画

2020年09月21日  | 移动技术网移动技术  | 我要评论
AnroidStudio中使用kotlin语言的自定义动画第一个练习,后面还会更新第二练习1.动画效果:开始点击start后,小球开始进入大球的嘴里,点击stop后,停止动画(还不知道哪个软件录制gif好,下去再搜, 现在只能口述了)2.主题思路分析:/*拆分为多个部分寻找关系每个部分的绘制寻找动画因子创建动画*/详细:拆分为多个部分: 嘴巴和小球寻找关系:大小 间距 位置,可以根据自己的要求设置每个部分的绘制:onDraw方法画笔paint 画布 canva

AnroidStudio中使用kotlin语言的自定义动画
第一个练习,后面还会更新第二练习
1.动画效果:
开始

点击start后,小球开始进入大球的嘴里,
点击start后

点击stop后,停止动画
(还不知道哪个软件录制gif好,下去再搜, 现在只能口述了)

2.主题思路分析:
/*

拆分为多个部分
寻找关系
每个部分的绘制
寻找动画因子
创建动画

*/
详细:
拆分为多个部分: 嘴巴和小球

寻找关系:大小 间距 位置,可以根据自己的要求设置
在这里插入图片描述

每个部分的绘制:
onDraw方法
画笔paint 画布 canvas 使用canvas.draw

寻找动画因子:
观察这个动画中什么在变
嘴的动画因子是开始的度数和最后度数的变化
小球的动画因子是圆心的x坐标

创建动画:
使用的是,ValueAnimator.ofFloat ,得到变化的一系列值
设置动画属性: duration repeat
监听值的变化,得到回调,同时使用invalidate,调用onDraw
动画调用的效果, 以及动画的播放、暂停、取消

3.代码:
3.1 先画出图形
自己定义的kotln的class代码

class MouseAnim: View {
    // 定义画笔, 只有在需要使用的时候才定义,使用懒加载
    // 懒加载使用的是val 不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)
    private val mPaint: Paint  by lazy {
        Paint().apply {
            color = Color.BLUE
            style = Paint.Style.FILL
        }
    }

    // 定义小球的半径
    private var bollRadius = 0f
    // 定义嘴巴的半径
    private var mouseRadius = 0f
    // 两者之间的距离
    private var span = 0f
    // 嘴巴的x坐标
    private var cx = 0f
    // 嘴巴的y坐标
    private var cy = 0f

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        if (width >= height){
            bollRadius = height/6f
            if (bollRadius*8.5f > width){
                bollRadius = width/8.5f
            }
        }else{
            bollRadius = width/8.5f
        }

        mouseRadius = bollRadius*3f
        span = 0.5f*bollRadius
        cx = (width-bollRadius*8.5f)+mouseRadius
        cy = height/2f

    }
    // 两种构造方法
    // 代码
    constructor(context: Context) :super(context){}
    // xml
    constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet){}

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

        canvas?.drawCircle(cx+4.5f*bollRadius, height/2f, bollRadius, mPaint)
    }
}

对应的xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.android.mymouselodinganimationauto1.MouseAnim
        android:id="@+id/mouseView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="30dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

运行结果:

3.2在上述代码中添加动画
kotlin代码

class MouseAnim: View {
    // 定义画笔, 只有在需要使用的时候才定义,使用懒加载
    // 懒加载使用的是val 不可变变量定义:val 关键字,只能赋值一次的变量(类似Java中final修饰的变量)
    private val mPaint: Paint  by lazy {
        Paint().apply {
            color = Color.BLUE
            style = Paint.Style.FILL
        }
    }

    // 定义小球的半径
    private var bollRadius = 0f
    // 定义嘴巴的半径
    private var mouseRadius = 0f
    // 两者之间的距离
    private var span = 0f
    // 嘴巴的x坐标
    private var cx = 0f
    // 嘴巴的y坐标
    private var cy = 0f
    // 嘴巴的动画
    private var mouseMoveView: ValueAnimator? = null
    // 小球的动画
    private var bollMoveView: ValueAnimator? = null
    // 两个动画需要同时动, 因此需要一个集合
    private var allAnim = AnimatorSet()

    // 找出动画因子
    // 嘴的动画因子
    private var mouseAngle = 0f
    // 小球的动画因子
    private var bollTransX = 0f

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        if (width >= height){
            bollRadius = height/6f
            if (bollRadius*8.5f > width){
                bollRadius = width/8.5f
            }
        }else{
            bollRadius = width/8.5f
        }

        mouseRadius = bollRadius*3f
        span = 0.5f*bollRadius
        cx = (width-bollRadius*8.5f)/2f+mouseRadius
        cy = height/2f

    }
    // 两种构造方法
    // 代码
    constructor(context: Context) :super(context){}
    // xml
    constructor(context: Context, attributeSet: AttributeSet): super(context, attributeSet){}

    override fun onDraw(canvas: Canvas?) {
        canvas?.drawArc(cx-mouseRadius, cy-mouseRadius, cx+mouseRadius, cy+mouseRadius, mouseAngle, 360f-2f*mouseAngle, true,mPaint)

        canvas?.drawCircle(cx+4.5f*bollRadius-bollTransX, height/2f, bollRadius, mPaint)
    }

    private fun createView(){
        if (mouseMoveView == null) {
            mouseMoveView = ValueAnimator.ofFloat(0f, 45f, 0f).apply {
                duration = 680
                repeatCount = ValueAnimator.INFINITE
                addUpdateListener {
                    mouseAngle = it.animatedValue as Float
                    invalidate()
                }
            }
        }

        if (bollMoveView == null) {
            bollMoveView = ValueAnimator.ofFloat(0f, 4.5f * bollRadius, 0f).apply {
                duration = 680
                repeatCount = ValueAnimator.INFINITE
                addUpdateListener {
                    bollTransX = it.animatedValue as Float
                    invalidate()
                }
            }
        }

        allAnim.apply {
            playTogether(mouseMoveView, bollMoveView)
        }
    }
    fun startAnim(){
        createView()
        if (allAnim.isPaused){
            allAnim.resume()
        }else{
            allAnim.start()
        }
    }

    fun stopAnim(){
        allAnim.pause()
    }
}

对应的xml代码,添加了两个button

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorAccent"
    tools:context=".MainActivity">

    <com.android.mymouselodinganimationauto1.MouseAnim
        android:id="@+id/mouseView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_marginTop="30dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/mStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/mStart"
        app:layout_constraintTop_toTopOf="@+id/mStart" />

    <Button
        android:id="@+id/mStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="start"
        app:layout_constraintEnd_toStartOf="@+id/mStop"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/mouseView" />

</androidx.constraintlayout.widget.ConstraintLayout>

在MainActivity里面的代码,按钮监听事件

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

        // view是指自己创建的类的id值
        mStart.setOnClickListener {
            mouseView.startAnim()
        }
        mStop.setOnClickListener {
            mouseView.stopAnim()
        }
    }
}

4.最后的运行
在这里插入图片描述
5.整体的结构目录
在这里插入图片描述

本文地址:https://blog.csdn.net/weixin_44614751/article/details/108701795

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网