一.前言 1.三种动画的关系
2.三种动画的继承关系
二.逐帧动画(Frame Animation) 简单讲就是把几个静态的图片(放在res/drawable/路径下)快速播放形成动画,实现的方式有 Xml方式 或者 Java代码,官方推荐使用 Xml 方式。
效果展示:
1. Xml方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android ="http://schemas.android.com/apk/res/android" android:oneshot ="true" > <item android:drawable ="@drawable/campfire01" android:duration ="200" /> <item android:drawable ="@drawable/campfire02" android:duration ="200" /> <item android:drawable ="@drawable/campfire03" android:duration ="200" /> <item android:drawable ="@drawable/campfire04" android:duration ="200" /> <item android:drawable ="@drawable/campfire05" android:duration ="200" /> <item android:drawable ="@drawable/campfire06" android:duration ="200" /> <item android:drawable ="@drawable/campfire07" android:duration ="200" /> <item android:drawable ="@drawable/campfire08" android:duration ="200" /> <item android:drawable ="@drawable/campfire09" android:duration ="200" /> <item android:drawable ="@drawable/campfire10" android:duration ="200" /> <item android:drawable ="@drawable/campfire11" android:duration ="200" /> <item android:drawable ="@drawable/campfire12" android:duration ="200" /> <item android:drawable ="@drawable/campfire13" android:duration ="200" /> <item android:drawable ="@drawable/campfire14" android:duration ="200" /> <item android:drawable ="@drawable/campfire15" android:duration ="200" /> <item android:drawable ="@drawable/campfire16" android:duration ="200" /> <item android:drawable ="@drawable/campfire17" android:duration ="200" /> </animation-list >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class MainActivity extends AppCompatActivity { AnimationDrawable animationDrawable; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = findViewById(R.id.frame_image_view); animationDrawable = (AnimationDrawable) imageView.getDrawable(); } public void start_frame_animation (View view) { animationDrawable.start(); } public void stop_frame_animation (View view) { animationDrawable.stop(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".MainActivity" android:orientation ="vertical" > <ImageView android:id="@+id/frame_image_view" android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/fire_frame_animation" android:scaleType="fitXY" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start" android:layout_alignParentStart="true" android:layout_marginStart="20dp" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:onClick="start_frame_animation" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="stop" android:layout_alignParentEnd="true" android:layout_marginEnd="20dp" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:onClick="stop_frame_animation" /> </RelativeLayout >
2.Java代码
Xml方式使用的 item,java代码使用public void addFrame(@NonNull Drawable frame, int duration)
方法达到相同的效果。
Xml方式直接在Xml布局文件里面给ImageView设置动画Xml文件(fire_frame_animation.xml)作为背景,java代码使用public void setImageDrawable(@Nullable Drawable drawable)
方法设置AnimationDrawable的对象为背景。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public class MainActivity extends AppCompatActivity { AnimationDrawable animationDrawable; @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); animationDrawable = new AnimationDrawable(); int [] resID = {R.drawable.campfire01,R.drawable.campfire02, R.drawable.campfire03, R.drawable.campfire04, R.drawable.campfire05,R.drawable.campfire06, R.drawable.campfire07,R.drawable.campfire08, R.drawable.campfire09,R.drawable.campfire10, R.drawable.campfire11,R.drawable.campfire12, R.drawable.campfire13,R.drawable.campfire14, R.drawable.campfire15,R.drawable.campfire16, R.drawable.campfire17}; for (int i = 0 ; i < resID.length; i++) { animationDrawable.addFrame(getResources().getDrawable(resID[i],null ),100 ); } ImageView imageView = findViewById(R.id.frame_image_view); imageView.setImageDrawable(animationDrawable); } public void start_frame_animation (View view) { animationDrawable.start(); } public void stop_frame_animation (View view) { animationDrawable.stop(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:app ="http://schemas.android.com/apk/res-auto" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".MainActivity" > <ImageView android:id="@+id/frame_image_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="start" android:layout_alignParentStart="true" android:layout_marginStart="20dp" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:onClick="start_frame_animation" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="stop" android:layout_alignParentEnd="true" android:layout_marginEnd="20dp" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:onClick="stop_frame_animation" /> </RelativeLayout >
三.补间动画(Tween Animation) 补间动画就是指开发者指定动画的开始、动画的结束的”关键帧”,而动画变化的”中间帧”由系统计算,并补齐。
补间动画有四种:
位移 TranslateAnimation
缩放 ScaleAnimation
旋转 RotateAnimation
透明度 AlphaAnimation
1. Xml方式
系统默认不会在 res 文件夹下面创建 anim 文件夹,我们需要手动创建 anim 文件夹。我们的动画xml文件就存放在这里面。
我们使用的AnimationUtils
的public static Animation loadAnimation(Context context, @AnimRes int id)
方法加载我们的动画xml文件。
四种方式共有的属性:
1 2 3 4 5 6 7 8 9 10 android:duration="3000" android:startOffset="1000" android:fillBefore="true" android:fillAfter="false" android:fillEnabled="true" android:repeatMode="restart" android:repeatCount="0" android:interpolator = @[package :]anim/interpolator_resource
① 位移 TranslateAnimation
Translate独有的属性:
1 2 3 4 android:fromXDelta="0" android:toXDelta="100" android:fromYDelta="0" android:toYDelta="100"
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 //动画 translate_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <translate xmlns:android ="http://schemas.android.com/apk/res/android" android:fromXDelta ="0" android:toXDelta ="100" android:fromYDelta ="0" android:toYDelta ="100" android:duration ="1000" android:repeatCount ="1" android:repeatMode ="restart" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class TranslateActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_translate); final View view = findViewById(R.id.translate_view); final Animation translate = AnimationUtils.loadAnimation(this , R.anim.translate_animation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(translate); } }); } }
运行效果:
② 缩放 ScaleAnimation
Scale独有的属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 android:fromXScale="1" android:toXScale="1.5" android:fromYScale="1" android:toYScale="1.5" android:pivotX="100%" android:pivotY="100%"
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 //动画 scale_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android ="http://schemas.android.com/apk/res/android" android:fromXScale ="1" android:toXScale ="1.5" android:fromYScale ="1" android:toYScale ="1.5" android:pivotX ="100%" android:pivotY ="100%" android:duration ="1000" android:repeatCount ="1" android:repeatMode ="restart" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ScaleActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_scale); final View view = findViewById(R.id.translate_view); final Animation scale = AnimationUtils.loadAnimation(this , R.anim.scale_animation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(scale); } }); } }
运行效果:
③ 旋转 RotateAnimation
Rotate独有的属性:
1 2 3 4 5 6 7 8 9 10 android:fromDegrees="0" android:toDegrees="270" android:pivotX="100%" android:pivotY="100%"
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 //动画 rotate_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android ="http://schemas.android.com/apk/res/android" android:fromDegrees ="0" android:toDegrees ="90" android:pivotX ="100%" android:pivotY ="100%" android:duration ="1000" android:repeatCount ="1" android:repeatMode ="restart" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class RotateActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rotate); final View view = findViewById(R.id.translate_view); final Animation rotate = AnimationUtils.loadAnimation(this , R.anim.rotate_animation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(rotate); } }); } }
运行效果:
④ 透明度 AlphaAnimation
Alpha独有的属性:
1 2 android:fromAlpha="1.0" android:toAlpha="0.0"
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 //动画 alpha_animation.xml 文件 <?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android ="http://schemas.android.com/apk/res/android" android:fromAlpha ="1" android:toAlpha ="0.5" android:duration ="1000" android:repeatCount ="1" android:repeatMode ="restart" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class AlphaActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_alpha); final View view = findViewById(R.id.translate_view); final Animation alpha = AnimationUtils.loadAnimation(this , R.anim.alpha_animation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(alpha); } }); } }
运行效果:
⑤ 组合
关于android:fillBefore
和android:fillEnabled
的使用。首先说结论,如果fillEnabled为false,那么不管fillBefore取何值,都是fillBefore为true的效果。
1.两个效果的实现:
View先在原位置从0.5倍放大到2倍,然后在从原位置的45度旋转到720度
。效果图和代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" android:fillBefore ="false" android:fillAfter ="false" > <scale android:fromXScale="0.5" android:toXScale="2.0" android:fromYScale="0.5" android:toYScale="2.0" android:pivotX="50%" android:pivotY="50%" android:duration="3000" android:fillEnabled="false" /> <rotate android:fromDegrees="45" android:toDegrees="720" android:pivotX="50%" android:pivotY="50%" android:duration="2000" android:startOffset="3000" android:fillEnabled="true" /> </set >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class SetActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_set); final View view = findViewById(R.id.translate_view); final Animation scale = AnimationUtils.loadAnimation(this , R.anim.set_animation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(scale); } }); } }
初始状态为View偏90度,大小为View本身大小的一半,在接下来的1秒内变为View本身大小的2倍,然后,再在接下来的2秒内旋转到720度的位置,最后变为View本身的大小
。运行效果如下:(其实就是第一个效果中的Xml代码去掉全部的android:fillEnabled=”true”和android:fillBefore=”false”,其他不变,就会达成我们当前所描述的效果)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" android:fillAfter ="false" > <scale android:fromXScale="0.5" android:toXScale="2.0" android:fromYScale="0.5" android:toYScale="2.0" android:pivotX="50%" android:pivotY="50%" android:duration="3000" /> <rotate android:fromDegrees="45" android:toDegrees="720" android:pivotX="50%" android:pivotY="50%" android:duration="2000" android:startOffset="3000" /> </set >
2.两种运行效果的解释:
除去全部的android:fillEnabled=”true”和android:fillBefore=”false”之后,fillEnabled默认为false,fillBefore默认为true。而fillEnabled为false、fillBefore为any
相当于fillEnabled为true且fillBefore为true
,也就是动画开始时,动画属性要设置成给与的样式,View偏90度,大小为View本身大小的一半
。
除去全部的android:fillEnabled=”true”和android:fillBefore=”false”之前,我们一开始设置动画集合的fillBefore为false,缩放动画的fillEnabled为false,也就是说初始的缩放状态是大小为View本身大小的一半
。旋转动画的fillEnabled为true,动画集合的fillBefore为false,也就是说初始的旋转状态是View本身的初始值
。结合起来就是View不偏转,大小为View本身大小的一半
。
2.Java代码 java代码主要是使用继承于 Animation 的 TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation,AnimationSet。和 Xml 共有的属性一样,这些类也共有对应的方法(来自父类 Animation):
1 2 3 4 5 6 7 8 9 10 public void setDuration (long durationMillis) public void setStartOffset (long startOffset) public void setFillBefore (boolean fillBefore) public void setFillAfter (boolean fillAfter) public void setFillEnabled (boolean fillEnabled) public void setRepeatMode (int repeatMode) public void setRepeatCount (int repeatCount) public void setInterpolator (Interpolator i)
① 位移 TranslateAnimation
1 2 3 4 5 public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class TranslateActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_translate); final View view = findViewById(R.id.translate_view); final TranslateAnimation translate = new TranslateAnimation(0 ,100 ,0 ,100 ); translate.setDuration(1000 ); translate.setRepeatCount(1 ); translate.setRepeatMode(Animation.RESTART); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(translate); } }); } }
运行效果:
② 缩放 ScaleAnimation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public ScaleAnimation (float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 public class ScaleActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_scale); final View view = findViewById(R.id.translate_view); final ScaleAnimation scale = new ScaleAnimation(1.0f ,1.5f ,1.0f ,1.5f ,Animation.RELATIVE_TO_SELF,1.0f ,Animation.RELATIVE_TO_SELF,1.0f ); scale.setDuration(1000 ); scale.setRepeatCount(1 ); scale.setRepeatMode(Animation.RESTART); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(scale); } }); } }
运行效果:
③ 旋转 RotateAnimation
1 2 3 4 5 6 7 8 9 10 11 12 13 public RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class RotateActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_rotate); final View view = findViewById(R.id.translate_view); final RotateAnimation rotate = new RotateAnimation(0f ,90f ,Animation.RELATIVE_TO_SELF,1.0f ,Animation.RELATIVE_TO_SELF,1.0f ); rotate.setDuration(1000 ); rotate.setRepeatCount(1 ); rotate.setRepeatMode(Animation.RESTART); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(rotate); } }); } }
运行效果:
④ 透明度 AlphaAnimation
1 2 3 public AlphaAnimation (float fromAlpha, float toAlpha)
运行效果的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class AlphaActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_alpha); final View view = findViewById(R.id.translate_view); final AlphaAnimation alpha = new AlphaAnimation(1.0f ,0.5f ); alpha.setDuration(1000 ); alpha.setRepeatCount(1 ); alpha.setRepeatMode(Animation.RESTART); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(alpha); } }); } }
运行效果:
⑤ 组合动画
1 2 3 AnimationSet public AnimationSet (boolean shareInterpolator) public void addAnimation (Animation a)
运行效果代码以及例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class SetActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_set); final View view = findViewById(R.id.translate_view); final AnimationSet animationSet = new AnimationSet(true ); animationSet.setFillBefore(false ); animationSet.setFillAfter(false ); ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f , 2.0f , 0.5f , 2.0f , Animation.RELATIVE_TO_SELF, 0.5f , Animation.RELATIVE_TO_SELF, 0.5f ); scaleAnimation.setDuration(3000 ); scaleAnimation.setFillEnabled(false ); RotateAnimation rotateAnimation = new RotateAnimation(45 , 720 , Animation.RELATIVE_TO_SELF, 0.5f , Animation.RELATIVE_TO_SELF, 0.5f ); rotateAnimation.setDuration(2000 ); rotateAnimation.setFillEnabled(true ); rotateAnimation.setStartOffset(3000 ); animationSet.addAnimation(scaleAnimation); animationSet.addAnimation(rotateAnimation); findViewById(R.id.start).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { view.startAnimation(animationSet); } }); } }
3.高级使用 ① 监听动画
Animation
类通过监听动画开始 / 结束 / 重复时刻来进行一系列操作,如跳转页面等等。
通过在 Java
代码里setAnimationListener()
方法设置。
若采取上述方法监听动画,每次监听都必须重写4个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart (Animation animation) { } @Override public void onAnimationEnd (Animation animation) { } @Override public void onAnimationRepeat (Animation animation) { } });
采用动画适配器AnimatorListenerAdapter
,解决实现接口繁琐的问题。
1 2 3 4 5 6 7 8 9 anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart (Animator animation) { } });
② Interpolator(插值器)
Android动画-插值器(Interpolator)
4.Activity 的切换效果实战 ① 系统预设
系统已经封装好了淡入淡出、左滑右滑的效果,具体使用如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Intent intent = new Intent (this ,Acvtivity.class); startActivity(intent); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); @Override public void finish () { super .finish(); overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); }
实际例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class MainActivity extends AppCompatActivity { @Override protected void onCreate (Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); final Intent intent = new Intent(this , SecondActivity.class); findViewById(R.id.fade_animation).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { startActivity(intent); overridePendingTransition(android.R.anim.fade_in,android.R.anim.fade_out); } }); findViewById(R.id.slide_animation).setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { startActivity(intent); overridePendingTransition(android.R.anim.slide_in_left,android.R.anim.slide_out_right); } }); } }
② 自定义切换效果
1> 淡入淡出 效果是采用透明度动画(Alpha
)。
fade_in.xml(淡入)
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <alpha android:duration ="1500" android:fromAlpha ="0.0" android:toAlpha ="1.0" /> </set >
fade_out.xml(淡出)
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <alpha android:duration ="1500" android:fromAlpha ="1.0" android:toAlpha ="0.0" /> </set >
在Java代码中设置
1 2 3 4 Intent intent = new Intent(MainActivity.this , SecActivity.class); startActivity(intent); overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
2> 左右滑动 效果
out_to_left.xml
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromXDelta="0%p" android:toXDelta="-100%p" /> </set >
in_from_right.xml
1 2 3 4 5 6 7 8 9 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android ="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromXDelta="100%p" android:toXDelta="0%p" /> </set >
在Java代码中设置效果
1 2 3 4 Intent intent = new Intent(MainActivity.this , SecActivity.class); startActivity(intent); overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);
3> 酷炫的Activity切换动画,打造更好的用户体验
5.补间动画原理
四.属性动画(Property Animation) 为什么需要属性动画?
补间动画 只能够作用在视图View
上,即只可以对一个Button
、TextView
、甚至是LinearLayout
、或者其它继承自View
的组件进行动画操作,但无法对非View
的对象进行动画操作。
补间动画 没有改变View的属性,只是改变视觉效果。
补间动画 动画效果单一。
工作原理
实现方式
实际开发中,建议使用Java代码实现属性动画:因为很多时候属性的起始值是无法提前确定的(无法使用XML设置),这就需要在Java
代码里动态获取。
XML方式具备重用性,即将通用的动画写到XML里,可在各个界面中去重用它。
1. ValueAnimator学习 实现动画的原理:通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果。如下图:
详细内容请看:Android动画-ValueAnimator
2.ObjectAnimator学习 动画的原理: 通过不断控制 值 的变化,再不断 自动 赋给对象的属性,从而实现动画效果。如下图:
详细内容请看:Android动画-ObjectAnimator
3.插值器(Interpolator)和 估值器(TypeEvaluator) 详细内容请看:
4.属性动画的使用小技巧 详细内容请看:Android动画-属性动画的使用小技巧
5.ValueAnimator类 & ObjectAnimator 类的区别 对比ValueAnimator
类 & ObjectAnimator
类,其实二者都属于属性动画,本质上都是一致的:先改变值,然后 赋值 给对象的属性从而实现动画效果。
区别在于:
ValueAnimator
类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;
ObjectAnimator
类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接 对对象属性进行操作;
参考文章 Android 逐帧动画:关于 逐帧动画 的使用都在这里了!
Android:这是一份全面 & 详细的补间动画使用教程
对Animation中的fillAfter,fillBefore,fillEnabled的理解
Android 动画:手把手带你深入了解神秘的插值器(Interpolator)
Android:属性动画的核心使用类ValueAnimator学习指南
Android:手把手带你深入了解神秘的估值器(TypeEvaluator)
Android 属性动画的ObjectAnimator类学习指南
Android 动画:这些属性动画的使用小技巧你了解吗
安卓动画学习(六)–xml实现属性动画