十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Android动画

Android动画 /res/anim/下存放定义补间动画的xml文件/res/animator/下存放定义属性动画的xml文件ImageDecoderAndroid9引入了Image Decoder,提供了更强大的图片解码支持,可以解码PNG、JPEG等静态态图片,也能直接解码GIF、WEBP等动画图片。Android9新增了支持HEIF格式,这种压缩格式具有超高的压缩比,相较JPEG格式,其文件大小可以压缩到只有其一半,且可保证近似的图像质量。当使用ImageDecoder解码GIF、WEBP等动画图片时,程序将会返回一个AnimatedImageDrawable(Android9新增的API)对象,调用AnimatedImageDrawable对象的start()方法开始执行动画。帧动画帧动画是一个Drawable对象AnimationDrawable使用animation-list.../标签来定义逐帧动画drawable资源其中使用item.../子元素定义动画的各帧,并指定各帧的持续时间使用android:oneshot设置是否只播放一次。然后把帧动画对象设置给ImageView的source或background。AnimationDrawable代表的动画默认是不播放的,必须在程序中调用start方法播放动画。补间动画补间(Tween)动画只需指定三个必要信息动画开始帧信息、动画结束帧信息、动画的持续时间无须逐一定义动画过程中的每一帧而动画变化的中间帧由系统计算并补齐或者叫补帧动画。补间动画可以分为两大类视图补间动画View Animation和属性补间动画Property Animation。视图补间动画视图动画是通过XML文件或代码定义动画效果作用于视图View的属性上如位置、大小、旋转等最后把动画对象设置给视图的startAnimation方法。即先直接构造通用动画Animation再把动画对象Animation传递给视图由视图启动动画。Animation类是抽象的视图动画类,它有如下几个子类AlphaAnimation:透明度改变的动画时要指定动画时要指定动画开始时的透明度、结束时的透明度和动画持续时间。其中透明度可从0变化到1。ScaleAnimation:大小缩放的动画时要指定动画时要指定动画开始时的缩放比(以X、Y轴的缩放参数来表示)、结束时的缩放比(以X、Y轴的缩放参数来表示),并指定动画持续时间。由于缩放时以不同点为中心的缩放效果并不相同,日因此指定缩放动画时还要通过pivotX、pivotY来指定缩放中心的坐标。TranslateAnimation:位移变化的动画时只要指定定动画开始时的位置(以X、Y坐标来表示)、结束时的位置(以X、Y坐标来表示),并打指定动画持续时间即可RotateAnimation:旋转动画。创建该动画时只要指定动画开始时的旋转角度、结束时的旋转角度转角度,并指定动画持续时间即可。由于旋转时以不同点为中心的旋转效果并不相同,因此指定旋转动画时还要通过pivotX、pivotY来指定旋转轴心的坐标。TranslateAnimation ‌只改变视图的绘制位置‌‌需通过setFillAfte设置是否改变实际布局属性‌。当点击区域仍位于原始位置‌即使视觉上已移动可能导致交互错位。‌Android 5.0 推荐使用 view.animate().translationX(...)‌属性动画更可靠且可支持硬件加速。插值InterpolatorInterpolator控制在动画期间需要动态补入多少顿,具体在动画运行的哪些时刻补入帧控制插入帧的行为。Interpolator根据特定算法计算出整个动画所需要动态插入帧的密度和位置最终实现动画帧的匀速、加速、减速、抛物线速度等各种速度变化。Interpolator是一个接口,可以通过实现Interpolator来控制动画的变化速度。Android为Interpolator提供了如下几个实现类,用于实现不同的动画变化速度。LinearInterpolator:动画以均匀的速度改变。AccelerateInterpolator:在动画开始的地方改变速度较慢,然后开始加速。AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,在中间的时候加速。CycleInterpolator:动画循环播放特定的次数,变化速度按正弦曲线改变。DecelerateInterpolator:在动画开始的地方改变速度较快,然后开始减速。在定义补间动画的set.../元素中设置android:interpolator属性,可指定为Android默认支持的Interpolator。例如:android:anim/linear_interpolatorandroid:anim/accelerate_interpolator。定义动画资源之后利用 AnimationUtils 工具类加载指定的动画资源加载成功后返回 Animation对象, 动画视图使用该对象作为播放参数。XML方式在res/anim目录下创建例如fade_in.xml?xml version1.0 encodingutf-8?set xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:fillAftertruealphaandroid:duration2000android:fromAlpha0.0android:interpolatorandroid:anim/linear_interpolatorandroid:toAlpha1.0 //set然后在代码中加载这个动画再应用到动画视图的播放方法中Animation fadeIn AnimationUtils.loadAnimation(context, R.anim.fade_in);view.startAnimation(fadeIn);代码方式直接在代码中创建动画然后应用给动画视图的动画启动方法。Animation fadeIn new AlphaAnimation(0, 1);fadeIn.setDuration(2000); // 设置动画持续时间fadeIn.setFillAfter(true); // 保持动画结束时的状态view.startAnimation(fadeIn);更多示例!--xml配置-- ?xml version1.0 encodingutf-8? set xmlns:androidhttp://schemas.android.com/apk/res/android android:interpolatorandroid:anim/accelerate_interpolator !--从屏幕右侧飞入-- translate android:fromXDelta100% android:toXDelta0% android:duration200/ !--向屏幕右侧飞出-- translate android:fromXDelta0% android:toXDelta100% android:duration200/ /set//代码加载 val translate: Animation? AnimationUtils.loadAnimation(menuPanel.context, com.bjxdljg.common.R.anim.anim_in_from_right) menuPanel.startAnimation(translate)//神图补间动画代码实现 //从屏幕右侧飞入 val translate: Animation TranslateAnimation(Animation.RELATIVE_TO_SELF,1f, Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f) translate.duration200 menuPanel.startAnimation(translate) //向屏幕右侧飞出 val translate: Animation TranslateAnimation(Animation.RELATIVE_TO_SELF,0f, Animation.RELATIVE_TO_SELF,1f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f) translate.duration200 menuPanel.startAnimation(translate) //属性补间动画代码实现 //从屏幕右侧飞入 menuPanel.translationXmenuPanel.width.toFloat() menuPanel.animate().translationX(0f).setDuration(200).start()自定义视图补间动画Animation是视图补间动画抽象基类,系统为该抽象基类提供实现了AlphaAnimation、RotateAnimation、ScaleAnimation、Translate Animation四个视图补间动画的基本形式。在实际项目中可能还需要一些更复杂的动画,比如让图片在三维空间内进行旋转动画等,这需要继承Animation实现自定义补间动画。为了控制视图进行三维空间的变换,需要借助于Android提供的android.graphics.Camera,这个Camera是一个空间变换工具,作用有点类似于Matrix,但功能更强大。属性补间动画属性动画是增强版的补间动画。属性动画直接作用于对象的属性上它的直接作用只是在时间线上不断修改任何类型对象的任何属性值。视图补间动画只能定义两个关键帧在透明度旋转缩放位移4个方面的变化,属性补间动画可以定义任何属性的变化。视图补间动画只能对UI组件执行动画,属性补间动画几乎可以对任何对象执行动画(不管它是否显示在屏幕上)。Animator类是抽象的属性动画类,它有如下几个子类ValueAnimator:是Animator的子类属性动画主要的时间引擎,它负责计算各个帧的属性值。它定义了属性动画的绝大部分核心功能,包括计算各帧的相关属性值,负责处理更新事件,按属性值的类型控制计算规则。属性动画主要由两方面组成:1计算各帧的相关属性值;2为指定对象设置这些计算后的值。ValueAnimator只负责第一方面内内容,因此程序员必须根据ValueAnimator计算并监听值更新来更新对象的相关属性值。ObjectAnimator:是ValueAnimator的子类,允许对指定对象的属性执行动画。在实际应用中,ObjectAnimator使用起来更加简单,因此更加常用用。在少数场景下,由于ObjectAnimator存在一些限制,可能需要考虑使用ValueAnimator。AnimatorSet:是Animator的子类,用于组合多个Animator,并指定多个Animator是按次序播放还是同时播放。属性动画分为两类ValueAnimator和ObjectAnimatorAnimatorSet用于组合多个动画。即先要由视图对象和其属性名称构造出动画对象Animator然后由动画对象Animator启动动画。ObjectAnimator继承了ValueAnimator,它可以直接将ObjectAnimator在动画过程中计算出来的值应用到指定对象的指定属性上因此使用ObjectAnimator就不需要注册AnimatorUpdateListener监听器了。使用ObjectAnimator的ofint()、ofFloat()或ofObject(静态方法创建CObjectAnimator时,需要指定具体的对象,以及对象的属性名。与ValueAnimator不同的是,使用ObjectAnimator有如下几个注意点。要为该对象对应的属性提供setter方法。调用ObjectAnimator的ofint()、ofFloat()或 ofobject()工厂方法时,如果values...参数只提供了一个值(本来需要提供开始值和结束值),那么该值会被认为为是结束值。该对象应该为该属性提供一个getter方法,该getter方法的返回值将被作为开始值。如果动画的对象不是View,为了能显示动画效果,可能还需要在onAnimationUpdate()事件监听方法中调用View.invalidate()方法来刷新屏幕的显示,比如对]Drawable对象的color属性执行动画。但如果是View定义的setter方法,如setAlpha()和setTraInslationX()等方法都会自动地调用invalidate()方法,因此不需要额外地调用invalidat()方法。Evaluator属性动画还需要利用一个Evaluator(计算器)工具类控制属性动画如何计算属性值。Android提供了如下Evaluator。IntEvaluator:用于计算int类型属性值的计算器。FloatEvaluator:用于计算float类型属性值的计算器。ArgbEvaluator:用于计算以十六进制形式表示的颜色值的计算器。TypeEvaluator:它是计算器接口,开发者可以通过实现该接口来实现自定义计算器。如果需要对int、float或者颜色值以外类型的属性执行属性动画,可能需要实现TypeEvaluator接口来实现自定义计算器。Android8还为AnimatorSet新增了如下方法。reverse():反向播放属性动画。通过reverse()方法则允许对动画进行倒播--以前可能需要定义两组动画,其中一组用于正向播放(比如放大、淡入);另一组用于反向播放(比如缩小、淡出),有了倒播功能之后,只需定义一组动画即可。long getCurrentPlayTime():获取动画的当前播放时间。setCurrentPlayTime(longplayTime):设置动画的播放时间。通过调用setCurrentPlayTime()方法,允许AnimatorSet动画直接调到指定时间点进行播放,不需要总是从头开始播放。使用属性动画的步骤如下。创建ValueAnimator或ObjectAnimator对象--既可从XML资源文件加载该动画资源,也可直接调用ValueAnimator或ObjectAnimator的静态工厂方法来创建动画。为Animator对象设置属性。如果需要监听Animator的动画开始事件、动画结束事件、动画重复事件、动画值改变事件,并根据事件提供相应的处理代码,则应该为Animattor对象设置事件监听器。如果有多个动画需要按次序或同时播放,则应使用AnimatorSet组合这些动画。调用Animator对象的start()方法启动动画。ViewPropertyAnimator‌android.view.ViewPropertyAnimator‌‌ 是 Android 提供的一个用于简化和优化对View对象属性进行动画处理的工具类。它并非继承自ValueAnimator或ObjectAnimator而是专门为View设计提供更简洁的链式调用语法并在多属性同时动画时提升性能。调用 view.animate().translationX()是使用 ‌ViewPropertyAnimator‌ 实现属性动画的一种常见方式用于对 View 沿 X 轴进行平移动画。使用SurfaceView实现动画View的绘图机制存在如下缺陷View缺乏双缓冲机制。当需要更新View上的图片时,必须重绘View上显示的整张图片。新线程无法直接更新View组件。Android提供了一个SurfaceView来代替View,在实现游戏绘图方面,SurfaceView比View性能高。SurfaceView与普通View其中一个重要的区别:View的绘图小必须在当前U1线程中进行而SurfaceView不会存在这个问题,因为SurfaceView的绘图是由SurfaceHolder来完成的。对于View组件,如果程序需要花较长的时间来更新绘图,那么主UI线程将会被阻塞,无法响应用户的任何动作;而SurfaceHolder则会启用新的线程去更新SurfaceView的绘制,因此不会阻塞主UI线程。一般来说,如果程序界面的动画元素较多,而且很多动画元素的移动都需要通过定时器来控制,就可以考虑使用SurfaceView。ViewFlipperViewFlipper可使用动画控制多个组件之间的切换效果。1.ViewFlipper和OnGestureListener手势接口实现简单手势动画要点如下ViewFlipper类继承自android.widget.ViewAnimator它可以对内部的视图做动画它支持2.0及以上。在布局中添加ViewFlipper视图ViewFlipper android:idid/ViewFlipper01 android:layout_widthfill_parent android:layout_heightfill_parent/ViewFlipper在ViewFlipper中添加各个viewflipper.addView(view1);flipper.addView(view2);实现OnGestureListener构造GestureDetector detector new GestureDetector(this);在重写activity的onTouchEvent方法public boolean onTouchEvent(MotionEvent event) {return this.detector.onTouchEvent(event);}实现onFling方法public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {if (e1.getX() - e2.getX() 120) {this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_in));this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_left_out));this.flipper.showNext();return true;} else if (e1.getX() - e2.getX() -120) {this.flipper.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_in));this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this, R.anim.push_right_out));this.flipper.showPrevious();return true;}return false;}2.动画文件在res\anim\*.xml中例如?xml version1.0 encodingutf-8?set xmlns:androidhttp://schemas.android.com/apk/res/androidtranslate android:fromXDelta100%p android:toXDelta0 android:duration500 /alpha android:fromAlpha0.1 android:toAlpha1.0 android:duration500 //set这个动画中包含两个动作translation动画fromXDelta 动画的开始X位置toXDelta 动画的结束X位置duration 持续时间。alpha透明度通道动画layer-listlayer-list中的item有topstart、end、bottom属性可以理解为内边距top就是paddingTopbottom就是paddingBottom。不推荐使用在Layer-List中直接动画。不建议直接在layer-list中使用动画因为layer-list主要用于组合静态图层。如果确实需要在第一层实现动画效果可以将该层单独作为一个视图例如ImageView然后通过代码或XML属性动画来控制这个视图的动画。对于位移动画建议使用单独的视图如ImageView并通过属性动画来控制而不是尝试在layer-list中直接实现。这样可以更灵活地控制动画效果并且代码更加清晰、易于维护。如果确实需要在一个复杂的背景中结合多个动画效果考虑将动画应用于单独的视图或使用矢量图和矢量动画。AnimatorSet在使用AnimatorSet时‌推荐每次使用时都新建一个实例而不是重用旧的AnimatorSet对象‌。重用AnimatorSet可能会导致 ‌循环依赖异常‌java.lang.IllegalStateException: circular dependencies cannot exist in animatorset尤其是在动画执行过程中被多次启动或中断后。这是因为AnimatorSet内部会记录动画之间的依赖关系如顺序、同时播放等当同一个实例被重复使用时这些依赖关系可能累积并形成循环引用从而引发崩溃。推荐做法‌每次使用都新建‌在需要启动动画时创建一个新的AnimatorSet实例并配置所需的动画。‌避免重复调用start()‌如果一个AnimatorSet已经在运行中不要再次调用start()这也会增加出现循环依赖的风险。‌如需复用动画对象复用的是ObjectAnimator‌如果多个地方需要使用相同的动画效果如缩放、移动可以复用ObjectAnimator对象但每次仍需将其添加到一个新的AnimatorSet中。总结‌不要重用‌AnimatorSet实例。‌总是新建‌AnimatorSet实例来管理动画组合。可以安全地‌复用‌ObjectAnimator或ValueAnimator等基础动画对象。这种做法能有效避免循环依赖错误确保动画稳定运行。‌ScrollerAndroid里Scroller类 是为了实现View平滑滚动的一个Helper类。通常在自定义的View时使用在View中定义一个私有成员mScroller new Scroller(context)。设置mScroller滚动的位置时并不会导致View的滚动通常是用mScroller记录/计算View滚动的位置再重写View的computeScroll()完成实际的滚动。
返回列表