适合这手机浏览器主页的网站,一站式做网站服务,网站迁移到别的服务器要怎么做,网络营销推广方法研究原文链接 Android Animation Made Easy
动画在任何一个GUI系统中都是一个非常重要的设计元素#xff0c;它可以让交互变得优雅#xff0c;让界面变得炫酷#xff0c;让操作变得更加的舒畅#xff0c;让状态过渡变得更加的顺滑#xff0c;对视觉效果有极大的提升#xff…原文链接 Android Animation Made Easy
动画在任何一个GUI系统中都是一个非常重要的设计元素它可以让交互变得优雅让界面变得炫酷让操作变得更加的舒畅让状态过渡变得更加的顺滑对视觉效果有极大的提升时而提升用户体验特别是对于移动应用来说更是如此。就好比水果平台最为吸引人的地方就在于其炫酷流畅的动画效果。早期的Android在动画这一块确实差不过近些年随着谷歌不断的加大力度在提升现在来说安卓在动画这一块已经跟水果差不多了。今天就来聊一聊关于动画的话题。 动画的种类
一般来说动画分为二个种类
逐帧动画(Frame Animation)也叫做Drawable Animation
也就是电影胶片式的一张张不同的画连在一起播放比较简单只需要准备足够帧数数量的图片就可以了。缺点也比较明显需要比较多的资源图片存储空间内存空间以及CPU资源。并且灵活性非常的差不能让普通的一段文字或者一个按扭进行动画。 针对某些特别简单的动画可以用此方式来实现比如像简单的进度条或者滑动引导提示等具体的方式就是
animation-list xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:oneshottrue item android:drawabledrawable/rocket_thrust1 android:duration200 /item android:drawabledrawable/rocket_thrust2 android:duration200 /item android:drawabledrawable/rocket_thrust3 android:duration200 /
/animation-list补间动画Tween Animation
补间动画比帧动画就要高级一些因为充分利用了计算机的特性只需要告诉起始状态和结束状态然后让计算机去计算中间的状态再不用把每一帧都告诉计算机了。在安卓中就是View Animation以及后来的强大的Property Animation。
动画的基本原理
动画其实就是一组快速播放的幻灯片每一张每一帧的状态略有不同快速连起来播放由于人的眼睛有视觉残留效应这就形成了动画。对于计算机程序来说一般的动画就是给定对象的初始和终末状态在一定时间内不断的计算中间过程并以视觉的方式展示出来这就是动画。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ujh0qqTO-1691408239181)(https://developer.android.com/images/animation/animation-linear.png)]
动画的关键要素
一个动画必须要有以下关键的要素
时长(Duration)也就 说播放动画的总时长系统默认是300ms时间插值器(Interpolation)就是动画的关键参数随时间要如何变化重播(Repeat)包括重播的次数以及方式次数好理解方式的意思是可以顺序的一遍一遍的播也是可以反着播延迟(Delay)动画启动的延时通常用在动画组合里面。
View Animation
这是从安卓一开始就支持的动画方式仅能对View对象生效使用起来也比较方便和简单通过组合和自定义插值器足以实现常用的视觉变幻如渐变旋转缩放和位移。
主要有四种位移(translation)透明度(alpha)旋转(rotation)和缩放(scaling)。还可以以集合的方式来把几个动画合在一起播放。可以设置动画的时长(duration)速率(interpolator)重复和事件的监听。 一些使用建议 所有这些东西都是放在android.view.animation包下面的所以这些东西只能用于View对象。其实绝大多数时候这也不是问题除了View还有啥要做动画呢。 TranslateAnimation只能是直线运动如果要曲线就得自定义可以参考这个。 scale可以实现水平或者垂直翻转。 动画的触发是当View需要invalidate的时候就会触发setAnimation指定的动画。所以如下代码会正常触发: TextView title; // 原来是GONE的
title.setVisibility(View.VISIBLE);
title.setAnimation(new AlphaAnimation(0.3f, 1f);不一定非要startAnimation 要注意动画前后View的状态。这个比较难受。因为动画过程仅是放一遍电影动画过程中仅是在View的绘制的时候对Canvas做变幻对View本身并没有影响通常的做法是给View Animation加上Listener在onAnimationEnd的时候去设置目标状态。
总的来说View animation简单易用大部分场景是可以满足需求的早期版本确实有一些缺陷内部状态在动画过程中会有问题但是最近新的Android版本上面已没有大问题所以当能满足需求时使用也没有问题。
属性动画Property Animation)
就像名字暗示那样从3.0开始一套新的动画API出现了可以描述为在一段时间内以一定的方式来改变某一个属性是这样的方式来做动画。所以它也可以做动画以外的事情。这套API的核心思想是在一段时间内让某些属性随着时间改变有点像中学的物理题。
属性动画就是根据时间来改变某一对象不一定非要是View的某一个属性至于某一时刻属性变化的值所产生的后果由使用者自定义因此你可以把它应用于任何对象。
它也与View一样可以组合可以设置事件监听。
与View动画最大的区别在于View动画仅是按要求放一遍电影不会对View的实际属性产生影响因此动画过程中以及完成后View仍是在原来的位置属性也不会变化。而属性动画则不是它会直接改变View的属性所以有些时候这个优势会很方便比如实现收起与展开的动画时Property动画会明显的优势
比如对于一个可以收起和弹出的动画就可以这样来实现
收起动画
private void animateCollapse() {AnimatorSet set new AnimatorSet();ObjectAnimator translate ObjectAnimator.ofFloat(mStatusPanel, translationY, 0f, mTranslationY);ObjectAnimator alpha ObjectAnimator.ofFloat(mStatusPanel, alpha, 1f, 0.75f);set.setDuration(250);set.setInterpolator(new AccelerateDecelerateInterpolator());set.playTogether(translate, alpha);set.start();}弹出动画:
private void animateExpansion() {AnimatorSet set new AnimatorSet();ObjectAnimator translate ObjectAnimator.ofFloat(mStatusPanel, translationY, mTranslationY, 0);ObjectAnimator alpha ObjectAnimator.ofFloat(mStatusPanel, alpha, 0.75f, 1f);set.setDuration(250);set.setInterpolator(new AccelerateDecelerateInterpolator());set.playTogether(translate, alpha);set.start();}如果要使用View animation也许也可以实现同样的效果但估计会很难因为要注意设置View的属性。比如说收起时并不是全hide而是半折叠状态就需要在AnimationListener#onAnimationEnd时去设置特殊的位置状态.
使用时候的建议 属性动画是post layout的所以所有属性的初始状态就是你在布局中指定的值动画是以此为基础开始的。 比较难使用的是translationX和translationY属性它们的定义是相对于left和top的值。或者理解为相对于layout之后的在父布局中的位置的左边和右边。比如 ObjectAnimator.ofFloat(mBar, translationY, 0, height);这个就是进入的动画一个View从其上头滑入。反过来: ObjectAnimator.ofFloat(mBar, translationY, height, 0);就是滑出。
ValueAnimator
这是属性动画的核心类其实它很好的诠释了什么是动画它就是把某个值在duration内按照插值器指定的方式从一个值变化到另一个值。看到这个类就可以感知到动画跟View其实一点关系都没有动画就是一个随时间变化 的数值而已。
ValueAnimator animation ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();这意思就是让一个浮点数变量在1秒内从0变化 到100。至于这个有什么具体的效果要看你如何应用这个随时间变化 的浮点数变量比如用于控制进度一般情况下都会将变化的数值用于改变View的视觉变幻形态但并不局限于此这里只是为了说明这个动画数值可以用于任何地方 animation.addUpdateListener(anim - {float t (float) anim.getAnimatedValue();mStatusPanel.setText(String.format(Temperature: %04.1f, t));});ObjectAnimator
它是ValueAnimator的一个子类增强了点功能它的作用是针对 给定的对象对其指定的某个属性做动画插值动画计算与前面提到的ValueAnimator是一样的只不过说它可以对某个对象的指定的属性做计算并改变这个属性
ObjectAnimator animation ObjectAnimator.ofFloat(textView, translationX, 100f);
animation.setDuration(1000);
animation.start();这意思就是说把动画计算出来的数值应用于一个textView的translationX属性上面。它与下面的代码用ValueAnimator来实现是完全等效的
ValueAnimator animation ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator updatedAnimation) {float animatedValue (float)updatedAnimation.getAnimatedValue();textView.setTranslationX(animatedValue);}
});由此可见ObjectAnimator就是多做了一层封装方便来操作而已。需要注意的是对象的属性必须要有setter和getter因为这里会用传进来的属性名字用反射去调用所以必须要有属性对应的settter和getter方法。
ViewPropertyAnimator
因为大多数情况下是对View做动画所以又封装出了一个专门用于View的属性动画工具也即ViewPropertyAnimator可以非常方便进行属性动画。用一个实例就会相当明了。
比如说想对某个View进行位置用ObjectAnimator就需要这么写
ObjectAnimator animX ObjectAnimator.ofFloat(myView, x, 50f);
ObjectAnimator animY ObjectAnimator.ofFloat(myView, y, 100f);
AnimatorSet animSetXY new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();但如果用ViewPropertyAnimator就会非常简洁
myView.animate().x(50f).y(100f);AnimatorSet
用于创建组合前面的例子已经可以看出来它怎么使用的了。当需要同时实现多个变幻时就可以把多个Animator用AnimatorSet来组合起来。这个类非常的灵活可以设置不同的时长延迟和重复。
插值器
插值器Interpolators用以调节数值与时间变化 的关系因为动画是有时长的是在duration内从某个数值变化 到另一数值而具体随时间怎么变则由插值器决定。默认是线性的比如250ms0f到100那么就是匀速运动。也可以加速的减速的先加速后减速先减速后加速。
android.view.animation内定义了大量的插值器可供使用。
在XML中来声明动画
与布局类似动画也是支持在XML中来声明的这样可以减少代码量加强复用。方式与方法与写代码差不多只不过是放在了XML里面如
set android:orderingsequentiallysetobjectAnimatorandroid:propertyNamexandroid:duration500android:valueTo400android:valueTypeintType/objectAnimatorandroid:propertyNameyandroid:duration500android:valueTo300android:valueTypeintType//setobjectAnimatorandroid:propertyNamealphaandroid:duration500android:valueTo1f/
/set这就声明了一个AnimatorSet是一个位移和渐变动画使用时用AnimatorInflater 来加载load一下就可以了
AnimatorSet set (AnimatorSet) AnimatorInflater.loadAnimator(myContext,R.animator.property_animator);
set.setTarget(myObject);
set.start();支持的根节点有三个AnimatorSetObjectAnimator和ValueAnimator
ValueAnimator - animatorObjectAnimator - objectAnimatorAnimatorSet - set
对于XML中使用ValueAnimator也是一样的定义好然后加载出来就可以用了其实跟前面用代码写是一样的
animator xmlns:androidhttp://schemas.android.com/apk/res/androidandroid:duration1000android:valueTypefloatTypeandroid:valueFrom0fandroid:valueTo-100f /ValueAnimator xmlAnimator (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {Overridepublic void onAnimationUpdate(ValueAnimator updatedAnimation) {float animatedValue (float)updatedAnimation.getAnimatedValue();textView.setTranslationX(animatedValue);}
});xmlAnimator.start();注意有一点需要注意的是因为View Animation也是支持用XML方式来定义的且是放在了res/anim下面。所以如果使用Property Animation 时要放在res/animator下面这个一定要注意。
View状态变化动画
从安卓一开始对于一些View的状态变化就可以设置不同的Drawable以给用户视觉上的交互 反馈最常见的比如按扭常规状态Focused状态和按压状态以及Disabled的状态不可点击可以设置不同的Drawable如icon或者颜色等以告诉用户。这个是叫做StateListDrawable。
现如今也可以针对 View的不同状态设置不同的动画了通过StateListAnimator来实现它的语法与前面提到的StateListDrawable类似亦是通过一个selector只不过其中的每个item都是animator而非drawable比如
?xml version1.0 encodingutf-8?
selector xmlns:androidhttp://schemas.android.com/apk/res/android!-- the pressed state; increase x and y size to 150% --item android:state_pressedtruesetobjectAnimator android:propertyNamescaleXandroid:durationandroid:integer/config_shortAnimTimeandroid:valueTo1.5android:valueTypefloatType/objectAnimator android:propertyNamescaleYandroid:durationandroid:integer/config_shortAnimTimeandroid:valueTo1.5android:valueTypefloatType//set/item!-- the default, non-pressed state; set x and y size to 100% --item android:state_pressedfalsesetobjectAnimator android:propertyNamescaleXandroid:durationandroid:integer/config_shortAnimTimeandroid:valueTo1android:valueTypefloatType/objectAnimator android:propertyNamescaleYandroid:durationandroid:integer/config_shortAnimTimeandroid:valueTo1android:valueTypefloatType//set/item
/selector这意思就是当点击的时候进行缩放动画把其保存在res/xml/animate_scale.xml这里需要注意StateListDrawable是可以直接保存在res/drawable/下面的但动画毕竟不是drawable是不可以放在res/drawable下面。
通过android:stateListAnimator添加给指定的View如
Button android:stateListAnimatorxml/animate_scale... /如果不在XML中设置用代码也可以先用AnimatorInflater把它加载出来然后调用View#setStateListAnimator即可。
设计与实现要符合标准
一个不争的事实是在安卓的早期版本的时候对动画支持并不友好因此当时很多GUI的设计都是采用水果平台的规范导致大量的头部appGUI交互特别是动画这一块都是尽可能 的去模仿水果平台。
但时代不一样了现在在谷歌加大了对安桌的支持力度后特别是当Material Design出来了以后从Android 5.0 Lollipop开始伟大的Google就发布了专门针对UED的设计语言Material Design它不再单单是设计规范了而是一个非常详细的设计语言具体到Icon怎么画动画怎么做。那么安桌的GUI交互设计与实现就要符合Material Design的规范了这样不但体验更符合安桌的风格实现起来也更加的顺手因为大量的标准库AndroidX的库和风格主题动画等等都是以Material Design为标准的开发人猿在实现的时候有更多的资源可以复用不用再重复的去造轮子。
Anyway官方的东西我们还是要学习的并尽可能的遵守的特别是关于Material Design和Animation。
参考资料
Animations and Transitionshttps://github.com/lgvalle/Material-AnimationsImplementing Material Design in Your Android app如何学习 Android Animation
原创不易打赏点赞在看收藏分享 总要有一个吧