Java教程

自定义动画的实现-实例

本文主要是介绍自定义动画的实现-实例,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一:效果

上面是一个大嘴在吃一个球,下面是三个球分别一大一小的变化

         

GitHub地址:https://github.com/luofangli/Custom_Animation

代码:

 

<?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.example.custom_animation.BigEatSmallCircle
        android:id="@+id/myview"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:background="@color/design_default_color_primary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.example.custom_animation.CircleFollowJump
        android:id="@+id/circleAnima"
        android:layout_width="0dp"
        android:layout_height="200dp"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="10dp"
        android:background="@color/black"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/myview" />
</androidx.constraintlayout.widget.ConstraintLayout>

package com.example.custom_animation

import android.animation.ValueAnimator
import android.animation.ValueAnimator.INFINITE
import android.animation.ValueAnimator.ofFloat
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.core.graphics.toRectF

class BigEatSmallCircle:View {
    //小圆的半径
    private var smallArcRadius = 0f
    //大圆的动画因子
    private var sweepAngle = 0f
    private var startAngle = 0f
    //小圆的x,y坐标
    private var smallCircleX = 0f
    private var smallCircleY = 0f
    //小圆x的最大距离
    private var smallCircleBigX = 0f
    //大圆的动画
    private var valueAnimatorBigArc = ValueAnimator()
    //小圆的动画
    private var valueAnimatorSmallCircle = ValueAnimator()
    //画大圆的paint
    private val  paintBigCircle: Paint by lazy {
        Paint().apply {
            style = Paint.Style.FILL
            color = Color.RED
        }
    }
    constructor(context: Context):super(context){}
    constructor(context: Context,attributeSet: AttributeSet):super(context,attributeSet){}

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        Log.v("lfl","在OnSizeChanged")
         ArcRect()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
       //画大圆
        canvas?.drawArc(ArcRect(),startAngle,sweepAngle,true,paintBigCircle)
       //画小圆
        canvas?.drawCircle(smallCircleX,smallCircleY,smallArcRadius,paintBigCircle)
    }
    //确定圆弧的矩形区域 并且确定小圆的x,y坐标
    private fun ArcRect():RectF{
        //距离画布左右边缘的距离为
        var xDistance = 0f
        //距离画布上下边缘的距离
        var yDistance = 0f
        //当画布的高度小于宽度时
        if (measuredHeight<measuredWidth){
            smallArcRadius = measuredHeight/6f
           xDistance = (measuredWidth-8.5f*smallArcRadius)/2
        }else{
            smallArcRadius = measuredWidth/8.5f
            yDistance = (measuredHeight-6*smallArcRadius)/2
        }
        //确定小圆的x,y坐标
        smallCircleBigX = xDistance+7.5f*smallArcRadius
        smallCircleY = yDistance+3*smallArcRadius
        //返回大圆的矩形区域
        return RectF(xDistance,yDistance,
                (xDistance+6*smallArcRadius).toFloat(),
                (yDistance+6*smallArcRadius).toFloat())
    }
    //大圆的动画因子的改变
   private  fun changBigArcAngle(){
      valueAnimatorBigArc =  ValueAnimator.ofFloat(0f,45f).apply {
            duration = 1000L
            repeatCount = INFINITE
            addUpdateListener {
                val value = it.animatedValue as Float
                startAngle = value
                sweepAngle = 360f-value*2
                invalidate()
            }
        }
        //小球移动的动画
        valueAnimatorSmallCircle = ValueAnimator.ofFloat(0f,5.5f*87.5f).apply {
            duration = 1000L
            repeatCount = INFINITE
            addUpdateListener {
                val value = it.animatedValue as Float
                smallCircleX = smallCircleBigX - value
                invalidate()
            }
        }
    }
    //启动动画
    fun startAnima(){
        changBigArcAngle()
        valueAnimatorBigArc.start()
        valueAnimatorSmallCircle.start()
    }
}

package com.example.custom_animation

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.util.Log
import android.view.CollapsibleActionView
import android.view.ContextMenu
import android.view.View

class CircleFollowJump:View {
    //圆的半径
    private var raduis = 0f
    //圆在y轴上的位置
    private var cy = 0f
    //圆的x的位置
    private val cxArray = mutableListOf<Float>()
    //存圆的半径
    private val raduisArray = arrayOf(0f,0f,0f)
    //存入动画
    private val valueAnimatorArray = mutableListOf<ValueAnimator>()
    //准备画笔
    private val paint_circle:Paint by lazy {
        Paint().apply {
            style = Paint.Style.FILL
            color = Color.RED
        }
    }
    constructor(context: Context):super(context){}
    constructor(context: Context,attributeSet: AttributeSet):super(context,attributeSet){}

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        sure_centerAndradius()
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        //画三个圆
       draw3circle(canvas)
    }
    //确定中心点,以及圆的最大半径
    private fun sure_centerAndradius(){
        //临时判断值,
        val temp = measuredHeight/2f
        if (7*temp>measuredWidth){
            //圆的半径大了,
            raduis = measuredWidth/7f
        }else{
            //圆的半径刚刚好
            raduis = temp
        }
        //在x轴上圆离两边的距离
        val xDistance = (measuredWidth-7*raduis)/2
        //在y轴上圆离两边的距离
        val yDistance = (measuredHeight-2*raduis)/2
        //圆中心点y
        cy = yDistance+raduis
        //将半径存入数组中
        //各圆中心点x
        for (i in 0..2){
            raduisArray[i] = raduis
            val cx = (xDistance+raduis+i*2.5*raduis).toFloat()
            cxArray.add(cx)
        }
    }
    //画三个圆
    private fun draw3circle(canvas: Canvas?){
        for (i in 0..2){
            canvas?.drawCircle(cxArray[i],cy,raduisArray[i],paint_circle)
        }
    }
    //动画因子的改变
   private  fun changeRadius(){
        Log.v("lfl","在改变因子方法中")
        for (i in 0..2){
            ValueAnimator.ofFloat(1f,0.1f,1f).apply {
                duration = 1000
                repeatCount = ValueAnimator.INFINITE
                startDelay = i*155L
                addUpdateListener {
                    val value = it.animatedValue as Float
                    //各圆半径为
                    raduisArray[i] = raduis*value
                    invalidate()
                }
                valueAnimatorArray.add(this)
            }
        }
    }
    //启动动画
    fun startAnima(){
        changeRadius()
        for (i in 0..2){
            valueAnimatorArray[i].start()
        }
    }

}

package com.example.custom_animation

import android.animation.ValueAnimator
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import kotlinx.android.synthetic.main.activity_main.*

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


    }
}



                    
这篇关于自定义动画的实现-实例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!