美文网首页
Android动画介绍

Android动画介绍

作者: 瓶子狗坏人 | 来源:发表于2019-04-24 18:01 被阅读0次
Android动画

ViewAnimation

  • 属性
    • 插值器
      Interpolator 是个接口,系统已经实现了几种插值器,在使用的时候,以LinearInterpolator为例

      在Xml中:

      android:interpolator="@android:anim/linear_interpolator"

      在代码中(Kotlin):

      interpolator = LinearInterpolator()
  • 部分属性中不同的值类型

    Java xml description
    Animation.ABSOLUTE 数值 10、50等数值,表示据坐标原点的距离
    Animation.RELATIVE_TO_SELF 数值% xml:50%, java:0.5, 再传入类型参数Animation.RELATIVE_TO_SELF,表示据坐标原点的距离为当前控件当前方向上50%的长度
    Animation.RELATIVE_TO_PARENT 数值%p xml:50%p, java:0.5, 再传入类型参数Animation.RELATIVE_TO_PARENT,表示据坐标原点的距离为父控件当前方向上50%的长度
  1. Common: 共有的属性

    name description
    duration 动画的执行时间 , ms
    fillAfter 保持动画执行结束后的状态 , boolean
    fillBefore 恢复到动画执行前的状态 , boolean
    interpolator 插值器,动画执行的过程中的速率变化, 比如先快后慢、匀速等
    repeatMode 动画再次执行的模式: reverse, 逆向执行;restart,从头开始
    repeatCount 动画执行的次数: infinite(-1)表示无限循环,要在具体的Animation中设置才有效
  2. Alpha

    name description
    toAlpha 动画结束时的透明度, 0.0~1.0
    fromAlpha 动画开始时的透明度, 0.0~1.0
  1. Rotate

    name description
    pivotX 作为旋转中心的X的值,值有三种类型
    pivotY 作为旋转中心的Y的值,值有三种类型
    fromDegrees 动画开始时相较于原始位置所处的角度
    toDegrees 动画结束时相较于原始位置所处的角度, 值为负数时逆时针旋转, 值为正数时顺时针旋转
  2. Scale

    name description
    pivotX 作为动画起始点的X的值,值有三种类型
    pivotY 作为动画起始点Y的值,值有三种类型
    fromXScale 动画开始时X方向相较于原始大小的缩放比例
    toXScale 动画结束时X方向相较于原始大小的缩放比例
    fromYScale 动画开始时Y方向相较于原始大小的缩放比例
    toYScale 动画结束时Y方向相较于原始大小的缩放比例
  3. Translate

    name description
    fromXDelta 动画开始时相较于原始位置X平移的距离,值有三种类型
    toXDelta 动画结束时相较于原始位置X平移的距离,值有三种类型
    fromYDelta 动画开始时相较于原始位置Y平移的距离,值有三种类型
    toYDelta 动画结束时相较于原始位置X平移的距离,值有三种类型
  4. Set

    name description
    shareInterpolator Set动画集合中的动画是否共享插值器, boolean
  • 应用

    1. LayoutAnimation

      name description
      delay 动画延迟播放时间: 用百分号表示基于Item动画的duration,0%,表示动画同步执行; 100% ,表示前一个动画执行完后才执行下一个
      animationOrder 子View动画播放顺序:normal,item的顺序;reverse,item的倒序;random,随机;
      animation 动画
      interpolator 插值器
       layout_animation.xml
          <?xml version="1.0" encoding="utf-8"?>
          <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
              android:animation="@anim/layout_set_anim"
              android:delay="15%"
              android:animationOrder="normal">
          </layoutAnimation>
      
       layout_set_anim.xml
          <?xml version="1.0" encoding="utf-8"?>
          <set xmlns:android="http://schemas.android.com/apk/res/android"
               android:duration="1000"
          >
          
              <translate
                      android:toXDelta="0%"
                      android:toYDelta="0%"
                      android:fromXDelta="0%"
                      android:fromYDelta="120%"/>
              <alpha
                      android:toAlpha="1.0"
                      android:fromAlpha="0.0"/>
           <!--   <scale
                      android:pivotX="50%"
                      android:pivotY="50%"
                      android:fromXScale="0.2"
                      android:fromYScale="0.2"
                      android:toXScale="1.0"
                      android:toYScale="1.0"/>-->
          
          </set>
      
    2. Activity之间的切换

      • 必须在Activity 的 startActivity 系列方法或finish之后调用
        Activity.overridePendingTransition(enterAnim, exitAnim)
      • 对所有的Activity都有效
        <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
              <!-- Customize your theme here. -->
              <item name="colorPrimary">@color/colorPrimary</item>
              <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
              <item name="colorAccent">@color/colorAccent</item>
              <item name="android:windowAnimationStyle">@style/activityAnimStyle</item>
          </style>
          
        <style name="activityAnimStyle" parent="@android:style/Animation.Activity">
              <item name="android:activityOpenEnterAnimation">@anim/act_next_in</item>
              <item name="android:activityOpenExitAnimation">@anim/act_next_current_out</item>
              <item name="android:activityCloseEnterAnimation">@anim/act_last_in</item>
              <item name="android:activityCloseExitAnimation">@anim/act_last_current_out</item>
          
          </style>
      
    3. Fragment之间的切换

    enterAnim: 指Fragment进入视图时的动画,exitAnim:退出视图时的动画

      FragmentActivity.getSupportFragmentManager()
                      .beginTransaction()
                      {.setCustomAnimations(enterAnim,exitExit) | .setCustomAnimations(enterAnim,exitAnim,popEnterAnim,popExitAnim)}
                      { .add().show() | .replace()}
                      .commit()
    
    

DrawableAnimation(FrameAnimation)

//开始动画
(testV.drawable as? AnimationDrawable)?.start()
  • activity_main.xml

     <?xml version="1.0" encoding="utf-8"?>
        <androidx.constraintlayout.widget.ConstraintLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layoutAnimation="@anim/layout_animation"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">
            <androidx.appcompat.widget.Toolbar
                    android:id="@+id/titleToolBar"
                    android:background="@color/colorPrimary"
                    android:layout_width="match_parent"
                    android:minHeight="?android:attr/actionBarSize"
                    app:layout_constraintTop_toTopOf="parent"
                    android:layout_height="wrap_content"/>
            <com.google.android.material.tabs.TabLayout android:layout_width="match_parent"
                                                        app:layout_constraintTop_toBottomOf="@+id/        titleToolBar"
                                                        app:layout_constraintLeft_toLeftOf="parent"
                                                        android:id="@+id/topTab"
                                                        app:tabMode="scrollable"
                                                        android:layout_height="?android:actionBarSize"/>
        
        
            <ImageView
                    android:id="@+id/testV"
                    app:layout_constraintTop_toBottomOf="@+id/topTab"
                    android:layout_width="100dp"
                    android:layout_height="100dp"
                    android:background="#689F38"
                    android:src="@drawable/drawable_animation"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
            />
            <ToggleButton
                    android:id="@+id/toggleB"
                    android:textOff="use XML"
                    android:textOn="use JAVA"
                    app:layout_constraintBottom_toBottomOf="parent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
        
        </androidx.constraintlayout.widget.ConstraintLayout>
        
    
  • AnimationDrawable

        <?xml version="1.0" encoding="utf-8"?>
        <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                        android:oneshot="false"
        >
            <item android:drawable="@drawable/img_0" android:duration="150"/>
            <item android:drawable="@drawable/img_1" android:duration="150"/>
            <item android:drawable="@drawable/img_2" android:duration="150"/>
            <item android:drawable="@drawable/img_3" android:duration="150"/>
            <item android:drawable="@drawable/img_4" android:duration="150"/>
            <item android:drawable="@drawable/img_5" android:duration="150"/>
            <item android:drawable="@drawable/img_6" android:duration="150"/>
        </animation-list>
    
    

PropertyAnimation

  1. 属性动画不仅仅局限与View,它的作用在于改变目标对象的属性,目标对象不仅是View
  2. View动画只是改变了View的视觉效果,并没有改变View的属性;属性动画则改变了属性。
    如一个用了View动画位移到新位置的按钮,它的点击响应位置还是在原来的位置,本身的属性并没有改变。
    属性动画的点击响应位置则会在新位置(点击响应的位置坐标与组件的位置坐标不是同一个)。
  • ValueAnimator

    1. 普通用法(ofInt(), ofFloat()...)
    • animator_int.xml
        <?xml version="1.0" encoding="utf-8"?>
        <animator xmlns:android="http://schemas.android.com/apk/res/android"
          android:repeatMode="restart"
          android:repeatCount="infinite"
          android:duration="3000"
          android:interpolator="@android:anim/linear_interpolator"
          android:valueType="colorType"
          android:valueFrom="@color/colorFrom"
          android:valueTo="@color/colorTo"
        />
      
    • code
        private val valueAnimator: ValueAnimator
            get() = if (useCode) ValueAnimator.ofInt(Color.parseColor("#008577"), Color.parseColor("#D81B60")).apply {
                repeatCount = ValueAnimator.INFINITE
                repeatMode = ValueAnimator.RESTART
                duration = 3000
                interpolator = AccelerateDecelerateInterpolator()
                addUpdateListener {
                //在回调中改变目标对象相应的属性值,达到动画效果
                    target.background = ColorDrawable(it.animatedValue as Int)
                }
            }
            else (AnimatorInflater.loadAnimator(this, R.animator.animator_int) as ValueAnimator).apply {
                addUpdateListener {
                    target.background = ColorDrawable(it.animatedValue as Int)
                }
            }
            
            //开始动画
            valueAnimator.start()
            //移除更新监听器来结束动画
            valueAnimator.removeUpdateListener(listener)
    
    1. 自定义(ofObject())
      //自定义的Evaluator
        class ScaleShapeEvaluator : TypeEvaluator<ScaleShape> {
            override fun evaluate(fraction: Float, startValue: ScaleShape, endValue: ScaleShape): ScaleShape {
                val x = startValue.x + fraction * (endValue.x - startValue.x)
                val y = startValue.y + fraction * (endValue.y - startValue.y)
        
                return ScaleShape(x, y)
            }
        } 
    
        ValueAnimator.ofObject(ScaleShapeEvaluator(), ScaleShape(0.5F, 0.2F), ScaleShape(2.0F, 3.0F)).apply {
                repeatCount = ValueAnimator.INFINITE
                repeatMode = ValueAnimator.RESTART
                duration = 2000
                interpolator = AccelerateDecelerateInterpolator()
                addUpdateListener(listener)
                start()
            } 
    
  • ObjectAnimator
  1. 普通用法
  • animator_object_rotate.xml

        <?xml version="1.0" encoding="utf-8"?>
        <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                        android:repeatMode="restart"
                        android:valueFrom="0"
                        android:valueTo="360"
                        android:interpolator="@android:anim/linear_interpolator"
                        android:propertyName="rotationX"
                        android:duration="1000"
                        android:repeatCount="infinite"
                        android:valueType="floatType"
        />
    
    val animator = ObjectAnimator.ofFloat(target, "rotationY", 0f, -360F).apply {
                repeatCount = ObjectAnimator.INFINITE
                repeatMode = ObjectAnimator.RESTART
                duration = 2000
                interpolator = LinearInterpolator()
            }
            or 
    val animator = AnimatorInflater.loadAnimator(this, R.animator.animator_object_rotate)   .apply {
                setTarget(target)
            }
            
    animator.start()       
    //设置目标为null 来取消动画       
    animator.setTarget(null)        
    
  1. 自定义
    对于一些没有的属性,可以通过装饰器模式来包装一下
//ShapeWrapper
class ShapeWrapper(private val target: View) {

    fun setShape(shape: ScaleShape) {
        target.layoutParams.apply {
            width = shape.x.toInt()
            height = shape.y.toInt()
        }
        target.requestLayout()
    }

    fun getShape(): ScaleShape {
        return ScaleShape(target.width.toFloat(), target.height.toFloat())
    }
}
//ScaleShape
data class ScaleShape(var x: Float, var y: Float)
//Evaluator
class ScaleShapeEvaluator : TypeEvaluator<ScaleShape> {
     override fun evaluate(fraction: Float, startValue: ScaleShape, endValue: ScaleShape): ScaleShape {
         val x = startValue.x + fraction * (endValue.x - startValue.x)
         val y = startValue.y + fraction * (endValue.y - startValue.y)

         return ScaleShape(x, y)
     }
}
//使用
val animator = ObjectAnimator.ofObject(
            ShapeWrapper(target),
            "shape",
            ScaleShapeEvaluator(),
            ScaleShape(100F, 100F),
            ScaleShape(500F, 500F)
        ).apply {
            repeatCount = ObjectAnimator.INFINITE
            repeatMode = ObjectAnimator.RESTART
            duration = 2000
            interpolator = LinearInterpolator()
        }

资源

例子

Android开发艺术探索 - 任玉刚

相关文章

网友评论

      本文标题:Android动画介绍

      本文链接:https://www.haomeiwen.com/subject/mvcngqtx.html