Android 动画基础知识学习(上)

来源:http://www.sh-fengwen.com 作者:家常菜谱 人气:197 发布时间:2019-09-07
摘要:学习资料: Android开发艺术探索 和Android应用开发之所有动画使用详解 学习资料: Android开发艺术探索 和Animation的api View动画 属性动画可以对任意对象的属性进行动画不仅仅是 View ,动

学习资料:Android开发艺术探索和Android应用开发之所有动画使用详解

学习资料:Android开发艺术探索和Animation的api

  1. View动画

属性动画可以对任意对象的属性进行动画不仅仅是View,动画默认时间间隔是300ms,默认帧率是100ms/帧

通过场景里的对象不断做图像变换(平移,缩放,旋转,透明度)从而产生动画效果,是一种渐近式动画,并支持自定义。

作用:在一个时间间隔内完成对一个对象从属性值到另一个属性值的改变。

  1. 帧动画

三个常用类:ValueAnimator,ObjectAnimator,AnimatorSet

帧动画其实也属于View动画。通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画效果,但图片过多过大会导致OOM

图片 1属性动画

  1. 属性动画

Java代码

属相动画通过动态地改变对象的属性从而达到动画效果。

private void initView() { Button bt =  findViewById(R.id.bt_object_animation_activity); ImageView iv = (ImageView) findViewById(R.id.iv_object_animation_activity); //改变背景属性 ValueAnimator colorAnim = ObjectAnimator.ofInt(iv, "backgroundColor", Color.parseColor("#FF4081"), Color.CYAN); colorAnim.setRepeatCount; colorAnim.setRepeatMode(ObjectAnimator.REVERSE); colorAnim.setDuration; colorAnim.setEvaluator(new ArgbEvaluator;//估值器 //动画集合 AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(iv, "rotationX", 0, 360),//绕x轴旋转360度 ObjectAnimator.ofFloat(iv, "rotation", 0, -90),//逆时针旋转90度 ObjectAnimator.ofFloat(iv, "translationX", 0, 90),//右移 ObjectAnimator.ofFloat(iv, "scaleY", 1, 0.5f),//y轴缩放到一半 ObjectAnimator.ofFloat(iv, "alpha", 1, 0.25f, 1)//透明度变换 ); //延迟一秒开始 set.setStartDelay; bt.setOnClickListener -> { //改变属性 位置 向下移动iv高的二分之一 ObjectAnimator.ofFloat(iv, "translationY", iv.getHeight.start(); //背景属性改变开始 colorAnim.start(); //集合动画 set.setDuration.start;}

重点在于属性动画的学习

轴点默认为View的中心点。

View动画的作用对象是View。支持四种典型动画效果:

常用的propertyName

  • 平移动画 TranslateAnimation
  • 缩放动画 ScaleAnimation
  • 旋转动画 RotateAnimation
  • 透明度动画 AlphaAnimation
  • rotationX 围绕x轴旋转
  • rotationY 围绕y轴旋转
  • rotation 围绕轴点旋转
  • translationX 在x轴方向上平移
  • translationY 在y轴方向上平移
  • scaleX 在x轴方向缩放
  • scaleY 在y轴方向缩放
  • alpha 透明度
  • width 宽度
  • height 高度

对于View动画,建议采用xml来定义动画,这样可读性更好

Animation的api

View动画的四种变换

1.2.1 ObjectAnimator

  • ObjectAnimator.ofFloat(Object target, String propertyName, float... values)

Constructs and returns an ObjectAnimator that animates between float values.

返回一个根据方法内的具体的values创建的ObjectAnimator对象

  1. Object target ,目标控件View的对象
  2. String propertyName,属性的名字
  3. float... values ,根据具体需求需要的属性值
  • ofPropertyValuesHolder(Object target, PropertyValuesHolder... values)

Constructs and returns an ObjectAnimator that animates between the sets of values specified in PropertyValueHolder objects

返回一个由PropertyValueHolder对象创建的ObjectAnimator对象

 public void byPropertyValuesHolder(ImageView iv) { PropertyValuesHolder pvh_1 = PropertyValuesHolder.ofFloat("rotationX", 0, 360); PropertyValuesHolder pvh_2 = PropertyValuesHolder.ofFloat("rotation", 0, -90); PropertyValuesHolder pvh_3 = PropertyValuesHolder.ofFloat("alpha", 1, 0.25f, 1); ObjectAnimator.ofPropertyValuesHolder(iv, pvh_1, pvh_2, pvh_3).setDuration.start();}
  • ofInt(Object target, String propertyName, int... values)

Constructs and returns an ObjectAnimator that animates between int values.

返回一个由int值属性创建的ObjectAnimator对象

  • setTarget(Object target)设置动画目标View
名称 标签 子类 效果
平移动画 <translate> TranslateAnimation 移动View
缩放动画 <scale> ScaleAnimation 放大或缩小View
旋转动画 <rotate> RotateAnimation 旋转View
透明度动画 <alpha> AlphaAnimation 改变View的透明度

1.2.2 ValueAnimator

  • ValueAnimatorsetEvaluator(new ArgbEvaluator设置估值器

  • addUpdateListener(ValueAnimator.AnimatorUpdateListener listener)

Adds a listener to the set of listeners that are sent update events through the life of an animation.

添加一个监听,可以用来在动画过程中改变属性

  • setRepeatCount设置动画的循环次数,默认为0,-1为无限循环

  • setStartDelay(long startDelay)设置动画开始的延迟时间

  • cancel()取消一个正在进行的动画。取消前,动画进行到哪个状态,取消后,就保持在那个状态。

  • end()结束动画。调用结束方法后,View会跳转到结束状态。如果动画设置了循环次数setRepeatCount()和重复模式setRepeatMode(ObjectAnimator.REVERSE),结束状态就要根据具体设置分析。

Animation属性:

1.2.3 AnimatorSet

  • playTogether(Animator... items)

Sets up this AnimatorSet to play all of the supplied animations at the same time.

同时播放所有的Animator动画对象。

  • playSequentially(Animator... items)

Sets up this AnimatorSet to play each of the supplied animations when the previous animation ends.

顺序播放Animator动画对象

  • setInterpolator(TimeInterpolator interpolator)

Sets the TimeInterpolator for all current child animations of this AnimatorSet.

设置插值器

xml属性 jav代码 作用
android:detachWallpaper setDetachWallpaper 是否在壁纸上运行
android:duration setDuration 动画的持续时间
android:fillAfter setFillAfter 动画结束后是否停留在结束位置
android:fillBefore setFillBefore 动画结束时是否还原开始位置
android:fillEnabled setFillEnabled 同上,与fillBefore相同
android:interpolator setInterpolator(Interpolator) 设置插值器
android:repeatCount setRepeatCount 重复次数
android:repeatMode setRepeatMode 有两种重复类型,reverse倒序回放,restart从头播放
android:startOffset setStartOffset 开启动画startAnimation(animation)之后等待执行运行动画的时间
android:zAdjustment setZAdjustment 表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal

1.2.4 Animator

直接子类:AnimatorSetValueAnimator间接子类:ObjectAnimatorTimeAnimator

Animator类的方法子类都可以直接使用。

  • addListener(Animator.AnimatorListener listener)

Adds a listener to the set of listeners that are sent events through the life of an animation, such as start, repeat, and end.

为动画添加一个监听过程的接口。如果不想实现AnimatorListener接口中的所有方法也可以继承AnimatorListenerAdapter

set.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) { toast; } @Override public void onAnimationEnd(Animator animator) { toast; } @Override public void onAnimationCancel(Animator animator) { toast; } @Override public void onAnimationRepeat(Animator animator) { toast; }});

实现了接口中全部的方法。

继承AnimatorListenerAdapter:

set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); toast; }});

根据实际需求,实现不同的方法。

  • addPauseListener(Animator.AnimatorPauseListener listener)

Adds a pause listener to this animator

为动画增加暂停监听

TimeInterpolator,时间插值器。用来根据时间流逝的百分比来计算出当前属性的值变化的百分比。

常用插值器:

名称 作用
LinearInterpolator 线性插值器。匀速动画
AccelerateDecelerateInterpolator 加速减速插值器
DecelerateInterpolator 匀减速插值器。动作越来越慢
BounceInterpolator 回弹插值器。到达平移后,回弹
CycleInterpolator 循环插值器。在两点间往还运动
PathInterpolator 路径插值器。根据单一方向定义的路径坐标运动
OvershootInterpolator 超越插值器。超出后,再返回来
AnticipateInterpolator 预期插值器。先反向运动再根据指定的方向运动

都是Interpolator的子类

TypeEvaluator,类型估值算法。用来根据当前属性变化改变的百分比来计算改变后的属性值。

  • IntEvaluator,针对整型属性
  • FloatEvaluator,针对浮点型属性
  • ArgbEvaluator,针对Color属性

图片 2模拟小球下落

private void initView() { Button bt =  findViewById(R.id.bt_interpolator_activity); ImageView iv = (ImageView) findViewById(R.id.iv_interpolator_activity); LinearLayout root = (LinearLayout) findViewById(R.id.root_interpolator_activity);//根布局 AnimatorSet set = new AnimatorSet(); set.setInterpolator(new BounceInterpolator; set.setDuration; //利用View的post方法拿到根布局的高度 root.post -> { //计算下降高度 int height = root.getHeight() - iv.getHeight() - bt.getHeight(); //设置动画 set.play(ObjectAnimator.ofFloat(iv, "translationY", height)); }); bt.setOnClickListener(v ->set.start; }

利用BounceInterpolator可以很方便的做出模拟小球下落的动画。也可以根据需求进行自定义插值器。

Object的属性abc做动画,必须满足2个条件:

  1. object必须提供setAbc()的方法。如果动画的时候没有传递初始值,还要提供getAbc()方法。因为系统要去abc的初始值。如果不满足,程序直接Crash
  2. objectsetAbc对属性abc所做的改变必须能够通过某种方法反映出来,比如UI改变之类的。这条不满足,动画无效但程序不会Crash

View动画既可以是单个动画,也可以是一些列动画组成。

2.2.1 改变Button的宽度

例如,想要利用属性对话来改变一个Button的宽度。

private void initView() { Button bt =  findViewById(R.id.bt_button_activity); bt.setOnClickListener -> performAnimate;}private void performAnimate(Button bt) { ObjectAnimator.ofInt(bt, "width", 500).setDuration.start();}

<set> 标签标示动画集合,对应于AnimationSet类,可以包含若干动画,也可以嵌套其他的动画集合。

2.2.2不起作用的原因

Button继承的TextView

/** * Makes the TextView exactly this many pixels wide. * You could do the same thing by specifying this number in the * LayoutParams. * * @see #setMaxWidth * @see #setMinWidth * @see #getMinWidth() * @see #getMaxWidth() * * @attr ref android.R.styleable#TextView_width */ @android.view.RemotableViewMethod public void setWidth(int pixels) { mMaxWidth = mMinWidth = pixels; mMaxWidthMode = mMinWidthMode = PIXELS; requestLayout(); invalidate(); } /** * Return the width of the your view. * * @return The width of your view, in pixels. */ @ViewDebug.ExportedProperty(category = "layout") public final int getWidth() { return mRight - mLeft; }

getWidth()方法View的方法,是可以获取Button高度的。setWidth()方法TextView和子类的专属方法。是用来设置TextView的最大宽度和最小宽度的,并不是用来设置TextView的宽度的方法。TextView的宽度对应于XMLandroid:layout_widthsetWidth方法对应的是android:width

也就是说:ButtonsetWidth()getWidth()对应的就不是一个属性。只满足的条件1,不满足条件2

  • android:interpolator动画集合所采用的的插值器,插值器影响动画的速度,比如非匀速动画就需要通过插值器来控制动画的播放过程。默认为@android:anim/accelerate_decelerate_interpolator,即加速加速插值器。

2.2.3 解决办法

有三种解决办法:

  • 如果有权限,给对象加上getset方法
  • 用一个类包装原始对象,间接提供getset方法
  • 采用ValueAnimation,监听动画过程,实现属性的改变

getset方法往往拿不到权限。

利用包装类方法:

private void initView() { Button bt =  findViewById(R.id.bt_button_activity); bt.setOnClickListener -> performAnimate(bt,bt.getWidth;} private void performAnimate(Button bt,int width) { ButtonWrapper wrapper = new ButtonWrapper; wrapper.setWidth; ObjectAnimator.ofInt(wrapper, "width", 500).setDuration.start();}private static class ButtonWrapper { private View target; public ButtonWrapper(View target) { this.target = target; } public int getWidth() { return target.getLayoutParams().width; } public void setWidth(int width) { target.getLayoutParams().width = width; target.requestLayout(); }}

拿到Button的宽度后,设置给ButtonWrapper。这样动画开始后,Button会从原始大小开始变化。

利用ValueAnimation方法:

private void initView() { Button bt =  findViewById(R.id.bt_button_activity); bt.setOnClickListener -> performAnimate(bt,bt.getWidth;} private void performAnimate(Button bt,int start, int end) { ValueAnimator valueAnimator = ValueAnimator.ofInt; //IntEvaluator对象,估值的时候使用 IntEvaluator intEvaluator = new IntEvaluator(); valueAnimator.addUpdateListener((animator -> { //获取当前动画的进度值 , 整型, 1到100 int currentValue =  animator.getAnimatedValue(); //获取当前进度的占整个动画过程的比例,浮点型, 0到1 float fraction = animator.getAnimatedFraction(); //直接利用整型估值器,通过比例计算宽度,然后Button设置 bt.getLayoutParams().width = intEvaluator.evaluate(fraction,start,end); bt.requestLayout; //开启动画 valueAnimator.setDuration.start();} 

监控动画过程,利用IntEvaluator估值器

动画基础知识大概介绍完,自定义TypeEvaluatorInterpolator以及配合自定义View更多高级的用法,以后再做补充。

接下来相当长的时间会用来学习自定义View。想通过一系列博客来记录学习,一开始先学习一些View的基础属性知识为学习自定义View做准备,再学习具体的测量,绘制过程,View的事件体系,工作原理。学习过程中间会加入继续对动画的深入学习,也可能会加入RxJava的后续学习或者其他的框架的学习。

  • android:shareInterpolator集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,子动画就需要单独指定所需的插值器或者使用默认值。

图片 3平移动画可以简单实现抖动效果,转成gif掉帧有点严重,没有抖起来

res下创建anim文件夹,文件名translate_animation.xml

xml文件代码:

<set xmlns:andro android:fillAfter="false" android:duration="100" android:repeatMode="restart" > <translate android:repeatCount="2" android:fromXDelta="-10" android:fromYDelta="-5" android:toXDelta="10" android:toYDelta="5" /></set>

java代码:

Button bt =  view.findViewById(R.id.bt_translate_fragment_translate);ImageView iv = (ImageView)view.findViewById(R.id.iv_translate_fragment_translate);//初始化动画Animation animation = AnimationUtils.loadAnimation(context, R.anim.translate_animation);//点击按钮开始动画bt.setOnClickListener -> iv.startAnimation(animation));
  • android:fromXDeltax的起始坐标值,可以为数值、百分数、百分数p。以View的左上角为坐标系原点。负为左,正为右。

图片 41.0 坐标图

  1. 数值: 10表示以当前View左上角坐标加10px为初始点
  1. 百分数: 50%表示以当前View的左上角加上当前View宽高的50%做为初始点
  2. 百分数p: 50%p表示以当前View的左上角加上父控件宽高的50%做为初始点
  • android:toXDeltax的结束坐标值
  • android:fromYDeltay的起始坐标值。负为上,正为下
  • android:toYDeltay的结束坐标值

例如,利用TranslateAnimation把一个Button改变了,点击移动后的Button是无效的,而点击Button移动前的原始空白位置会响应Button的点击事件。

图片 5缩放动画

xml代码:

<set xmlns:andro android:duration="300" android:fillAfter="false" android:repeatMode="reverse"> <scale android:fromXScale="0.5" android:fromYScale="0.5" android:pivotX="-100" android:pivotY="-100" android:repeatCount="2" android:toXScale="1" android:toYScale="1" /></set>
  • android:fromXScale 水平方向的缩放值,数字代表比例。1.0是不缩放

  • android:fromYScale 垂直方向的缩放值

  • android:toXScale 水平方向的结束值

  • android:toYScale 垂直方向的结束值

  • android:pivotX 缩放的轴点的x轴的坐标。轴点为View的左上角

  • android:pivotY 缩放的轴点的y轴的坐标

默认情况下轴点为View的中心点

感觉书上这里和我实际测试有些出入,我感觉默认是View的左上角。不晓得是我哪里搞错了,希望可以指出。感觉坐标系就是自己上面画的那个1.0坐标图

图片 6旋转动画

xml代码:

<set xmlns:andro android:duration="300" android:repeatMode="reverse"> <rotate android:fromDegrees="0" android:pivotX="235" android:pivotY="150" android:repeatCount="2" android:toDegrees="360" /></set>
  • android:fromDegrees 旋转开始的角度
  • android:toDegrees 旋转结束的角度
  • android:pivotX 旋转的轴点的x坐标
  • android:pivotY 旋转的轴点的y坐标

图片 7透明度动画

本文由美高梅游戏平台网站发布于家常菜谱,转载请注明出处:Android 动画基础知识学习(上)

关键词:

上一篇:没有了

下一篇:没有了

最火资讯