Android 动画总结

Android 动画总结,第1张

概述Android动画总结逐帧动画补间动画属性动画Android开发中,动画特效是经常遇到的,接下来对这块知识点做一下总结。一.逐帧动画逐帧(Frame)动画,就是动画过程的每张静态的图片都收集起来,然后由Android来控制依次展示这些静态图片,再利用人眼的“视觉残留”原理,给用户呈现动画的 AndroID 动画总结逐帧动画补间动画属性动画

AndroID开发中,动画特效是经常遇到的,接下来对这块知识点做一下总结。

一.逐帧动画

逐帧(Frame)动画,就是动画过程的每张静态的图片都收集起来,然后由AndroID来控制依次展示这些静态图片,再利用人眼的“视觉残留”原理,给用户呈现动画的错觉。(逐帧动画的原理和放电影的原理一致)

定义逐帧动画
在< animation-List… />元素中使用< item…/ >子元素定义动画的全部帧即可
<?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/ic_frame0" androID:duration="60"/>    <item androID:drawable="@drawable/ic_frame1" androID:duration="60"/>    <item androID:drawable="@drawable/ic_frame2" androID:duration="60"/>    <item androID:drawable="@drawable/ic_frame3" androID:duration="60"/>    <!--下面忽略多个item--></animation-List>

上面的xml文件定义了一个逐帧动画资源,androID:oneshot为false指的可以循环播放动画

使用逐帧动画
class MainAnimActivity : AppCompatActivity() {    overrIDe fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentVIEw(R.layout.activity_main_anim)        val framImageVIEw = findVIEwByID<ImageVIEw>(R.ID.fram_imge)        val playAniBtn = findVIEwByID<button>(R.ID.play_btn)        val stopAniBtn = findVIEwByID<button>(R.ID.stop_btn)        val anim = framImageVIEw.background        playAniBtn.setonClickListener{v ->            if (anim is AnimationDrawable) {                anim.start()            }        }        stopAniBtn.setonClickListener {v ->              if (anim is AnimationDrawable) {                anim.stop()            }        }    }}

AnimationDrawble(An object used to create frame-by-frame animations)代表的动画默认不播放,提供如下方法来开始、结束动画
start() 开始播放动画
end() 结束动画

代码创建逐帧动画
	val animationDrawable = AnimationDrawable()    animationDrawable.addFrame(resources.getDrawable(R.drawable.ic_frame0), 60)    animationDrawable.addFrame(resources.getDrawable(R.drawable.ic_frame1), 60)    animationDrawable.addFrame(resources.getDrawable(R.drawable.ic_frame2), 60)    animationDrawable.addFrame(resources.getDrawable(R.drawable.ic_frame3), 60)    animationDrawable.isOneshot = false    	framImageVIEw.background = animationDrawable    playAniBtn.setonClickListener{v ->        animationDrawable.start()    }    stopAniBtn.setonClickListener {v ->        animationDrawable.stop()    }
二.补间动画

补间动画,就是指开发者只需指定动画开始、动画结束等“关键帧”,而动画变化的“中间帧”由系统计算并补齐。

AndroID使用Animation代表抽象的动画类
包含如下几个子类:AlphaAnimation(透明度动画)、ScaleAnimation(缩放动画)、TranslateAnimation(位移动画)、RotationAnimation(旋转动画)

AnimationSet : 组合多个补间动画时使用

使用补间动画

res/anim/tween_anim.xml

<?xml version="1.0" enCoding="utf-8"?><set xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:interpolator="@androID:anim/linear_interpolator">    <!--缩放 -->    <scale        androID:duration="3000"        androID:fillAfter="true"        androID:fromXScale="1.0"        androID:fromYScale="1.0"        androID:pivotX="50%"        androID:pivotY="50%"        androID:toXScale="0.1"        androID:toYScale="0.1" />    <!--透明度-->    <Alpha        androID:duration="3000"        androID:fromAlpha="1"        androID:toAlpha="0.05" />    <!-- 旋转 -->    <rotate        androID:duration="3000"        androID:fromdegrees="0"        androID:pivotX="50%"        androID:pivotY="50%"        androID:todegrees="180" />    <!--平移-->    <translate        androID:duration="3000"        androID:fromXDelta="100"        androID:fromYDelta="100"        androID:toXDelta="200"        androID:toYDelta="100" /></set>
//通过AnimationUtils得到代表动画的Animation之后,就可以调用vIEw的startAnimation(Animation anim)方法开始对该vIEw执行动画了val loadAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim)        playAniBtn.setonClickListener{v ->            framImageVIEw.startAnimation(loadAnimation)        }
代码创建补间动画
//透明度动画val AlphaAnimation = AlphaAnimation(1f, 0f)AlphaAnimation.duration = 3000//旋转动画/**  创建一个旋转动画对象*  入参列表含义如下:*  1.fromdegrees:从哪个角度开始旋转*  2.todegrees:旋转到哪个角度结束*  3.pivotXType:旋转所围绕的圆心的x轴坐标的类型,有ABSolUT绝对坐标、relative_TO_SELF相对于自身坐标、relative_TO_PARENT相对于父控件的坐标*  4.pivotXValue:旋转所围绕的圆心的x轴坐标,0.5f表明是以自身这个控件的一半长度为x轴*  5.pivotYType:y轴坐标的类型*  6.pivotYValue:y轴坐标*/val rotateAnimation = RotateAnimation(0f, 360f, Animation.relative_TO_SELF, 0.5f,        Animation.relative_TO_SELF, 0.5f);rotateAnimation.duration = 3000//缩放动画/**  创建一个缩放效果的动画*  入参列表含义如下:*  fromX:x轴的初始值*  toX:x轴缩放后的值*  fromY:y轴的初始值*  toY:y轴缩放后的值*  pivotXType:x轴坐标的类型,有ABSolUT绝对坐标、relative_TO_SELF相对于自身坐标、relative_TO_PARENT相对于父控件的坐标*  pivotXValue:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴*  pivotYType:y轴坐标的类型*  pivotYValue:轴的值,0.5f表明是以自身这个控件的一半长度为y轴*/val scaleAnimation = ScaleAnimation(1f, 0.8f, 1f, 0.8f, Animation.relative_TO_SELF, 0.5f, Animation.relative_TO_SELF, 0.5f)scaleAnimation.duration = 3000//平移动画/* *  创建一个移动动画效果 *  入参的含义如下: *  fromXType:移动前的x轴坐标的类型 *  fromXValue:移动前的x轴的坐标 *  toXType:移动后的x轴的坐标的类型 *  toXValue:移动后的x轴的坐标 *  fromYType:移动前的y轴的坐标的类型 *  fromYValue:移动前的y轴的坐标 *  toYType:移动后的y轴的坐标的类型 *  toYValue:移动后的y轴的坐标 */val translateAnimation = TranslateAnimation(Animation.relative_TO_SELF, 0f, Animation.relative_TO_SELF, 0.2f,        Animation.relative_TO_SELF, 0f, Animation.relative_TO_SELF, 0.2f)translateAnimation.duration = 3000playAniBtn.setonClickListener { v ->    val animationSet = AnimationSet(true)    animationSet.addAnimation(AlphaAnimation)    animationSet.addAnimation(rotateAnimation)    animationSet.addAnimation(scaleAnimation)    animationSet.addAnimation(translateAnimation)    //播放组合补间动画    framImageVIEw.startAnimation(animationSet)    //播放单一补间动画    //framImageVIEw.startAnimation(AlphaAnimation)}
补间动画只是去改变vIEw的展示效果,不会真正改变vIEw的属性
		val translateAnimation = TranslateAnimation(Animation.relative_TO_SELF, 0f, Animation.relative_TO_SELF, 1.5f, Animation.relative_TO_SELF, 0f, Animation.relative_TO_SELF, 0f)        translateAnimation.fillAfter = true                //延迟2秒执行平移动画         //对比平移前点击按钮和平移后点击按钮的现象        mHandler.postDelayed(Runnable { mTransBtn?.startAnimation(translateAnimation) }, 2000)        		mTransBtn?.setonClickListener {            Toast.makeText(this@MainActivity, getString(R.string.click_trans_btn), Toast.LENGTH_SHORT).show()         }

平移后的按钮无法触发我们注册的点击事件,而此时平移前按钮的位置是可以触发该点击事件的,因为实际上这个按钮还是停留在平移前的位置,只不过补间动画将这个按钮绘制到了平移后的位置

注:属性动画对vIEw属性进行动画,解决了该问题

三.属性动画

属性动画,可以定义任何属性的变化,从某种角度来看,属性动画是增强版的补间动画
1.补间动画只能定义在透明度、旋转、缩放、位移,这4个方面的变化,但属性动画可以定义任何属性的变化
2.补间动画只能对ui组件执行动画,但属性动画几乎可以对任何对象执行动画(不管是否显示在屏幕上)

Animator 提供了创建属性动画的基类,基本不会直接使用该类,通常只用于被继承并重写它的相关方法

ValueAnimator:主要负责计算各帧的属性值,更新对象的相关属性值时使用
ObjectAnimator:是ValueAnimator的子类,对指定对象的属性执行动画时使用
AnimatorSet:组合多个属性动画时使用

使用ObjectAnimator属性动画
		//透明度属性动画        mAlphaAnimator = ObjectAnimator.offloat(mMylove, "Alpha", 0.2f, 1f)        //mAlphaAnimator?.start()  //使用Alpha属性动画        //缩放属性动画        mScaleAnimatorX = ObjectAnimator.offloat(mMylove, "scaleX", 1f, 1.1f)        mScaleAnimatorY = ObjectAnimator.offloat(mMylove, "scaleY", 1f, 1.1f)        //组合属性动画        mAnimatorSet = AnimatorSet()        mAnimatorSet?.duration = 3000        mAnimatorSet?.playTogether(mScaleAnimatorX, mScaleAnimatorY, mAlphaAnimator)        mAnimatorSet?.start()  //使用组合属性动画
使用ValueAnimator属性动画
		//ValueAnimator属性动画        mProgressAnimator = ValueAnimator.ofInt(0, 100)        mProgressAnimator?.setDuration(3000)        mProgressAnimator?.addUpdateListener(AnimatorUpdateListener { animation ->            Log.i(TAG, "onAnimationUpdate :: " + animation.animatedValue)            mProgressbar?.progress = (animation.animatedValue as Int)        })        mProgressAnimator?.addListener(object : Animator.AnimatorListener {            overrIDe fun onAnimationStart(animation: Animator) {                Toast.makeText(this@MainActivity, "动画开始", Toast.LENGTH_SHORT).show()            }            overrIDe fun onAnimationEnd(animation: Animator) {                Toast.makeText(this@MainActivity, "动画结束", Toast.LENGTH_SHORT).show()            }            overrIDe fun onAnimationCancel(animation: Animator) {                Toast.makeText(this@MainActivity, "动画取消", Toast.LENGTH_SHORT).show()            }            overrIDe fun onAnimationRepeat(animation: Animator) {                Toast.makeText(this@MainActivity, "动画重复", Toast.LENGTH_SHORT).show()            }        })		//色值ValueAnimator属性动画		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) {            mcolorAnimator = ValueAnimator.ofArgb(-0x1, -0x10000, -0xffff01, -0xff0100)        }        mcolorAnimator?.duration = 3000        mcolorAnimator?.addUpdateListener { animation -> mStartBtn?.setBackgroundcolor((animation.animatedValue as Int)) }
xml文件定义属性动画

res/animator/animator_set.xml

<?xml version="1.0" enCoding="utf-8"?><set xmlns:androID="http://schemas.androID.com/apk/res/androID">    <objectAnimator        androID:duration="3000"        androID:propertyname="Alpha"        androID:valueFrom="0.2"        androID:valueto="1.0"        androID:valueType="floatType">    </objectAnimator>    <objectAnimator        androID:duration="3000"        androID:propertyname="scaleX"        androID:valueFrom="1.0"        androID:valueto="1.1"        androID:valueType="floatType">    </objectAnimator>    <objectAnimator        androID:duration="3000"        androID:propertyname="scaleY"        androID:valueFrom="1.0"        androID:valueto="1.1"        androID:valueType="floatType">    </objectAnimator></set>

res/animator/animator_Alpha.xml

<?xml version="1.0" enCoding="utf-8"?><objectAnimator xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:duration="3000"    androID:propertyname="Alpha"    androID:valueFrom="0.2"    androID:valueto="1.0"    androID:valueType="floatType"></objectAnimator>

代码中使用在xml中定义的属性动画

		//加载xml中属性动画        val animatorset = AnimatorInflater.loadAnimator(this, R.animator.animator_set) as AnimatorSet        val animator = AnimatorInflater.loadAnimator(this, R.animator.animator_Alpha)        //使用组合属性动画        animatorset.setTarget(mMylove)        animatorset.start()        //使用属性动画        animator.setTarget(mMylove)        animator.start()

在使用过程中,可以选择合适的动画进行动画效果实现

传送门:https://github.com/xiaoai-summer/myKotlinDemo

总结

以上是内存溢出为你收集整理的Android 动画总结全部内容,希望文章能够帮你解决Android 动画总结所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1022101.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存