闲扯:
现在好多APP真的是炫酷阿,人家那UI做的漂亮,可是有多动画是咋实现的呢?今天就学习一下。
之前用的顶多就是做一个动态的dialog。。。没有审美的人说多了都是泪阿,今天在这虐狗的日子,我就不去电影院买隔着的座了也不去小饭馆自己占着双人的小桌了,还是踏实的干点该干的事吧,进入主题。
动画效果的实现:
在安卓3.0以前有两种方法:
- 帧实现(Frame)
- 补间动画(Tweened)
- alpha —— 渐变透明动画
- scale —— 渐变尺寸伸缩
- transition —— 位置转移
- rotate —— 旋转动画
安卓3.0以后
新添加了属性动画(property animation)
好了,现在一个一个开始学习。
帧实现(Frame)
帧动画是最容易实现的一种动画,这种动画更多的依赖于完善的UI资源,他的原理就是将一张张单独的图片连贯的进行播放,
从而在视觉上产生一种动画的效果;
需要:
- 所有动画的图片,放在drawable文件夹下;
- xml文件定义AnimationDrawable;
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/a_0"
android:duration="100" />
<item
android:drawable="@drawable/a_1"
android:duration="100" />
<item
android:drawable="@drawable/a_2"
android:duration="100" />
</animation-list>
- Java启动动画,将Drawable作为View的北京并通过Drawable来播放动画;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame_animation);
ImageView animationImg1 = (ImageView) findViewById(R.id.animation1);
**animationImg1.setImageResource(R.drawable.frame_anim1);
AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg1.getDrawable();
animationDrawable1.start();**
}
注:
- android:oneshot=”false” ,这个oneshot 的含义就是动画执行一次(true)还是循环执行多次。
- 帧动画使用比较简单,但是比较容易引起OOM,所有使用帧动画的时候应尽量避免使用过多尺寸较大的图片。
之前一直用的。。。只是入门级的。。。
补间动画
补间动画又可以分为四种形式,分别是:
- alpha(淡入淡出)
- translate(位移)
- scale(缩放大小)
- rotate(旋转)
实现:
- xml文件——代码会更容易书写和阅读,同时也更容易复用。建议采用xml来定义动画,因为xml格式的动画 可读性更好。
- 可以是单个动画,也可以由一系列的动画组成。
- 通过Animation的setAnimationListener方法可以给View动画添加过程监听。
实现流程:
①在res/anim/ 文件夹下定义动画实现方式;
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 渐变透明度动画效果 -->
<!--
透明度控制动画效果 alpha
浮点型值:
fromAlpha 属性为动画起始时透明度
toAlpha 属性为动画结束时透明度
说明:
0.0表示完全透明
1.0表示完全不透明
以上值取0.0-1.0之间的float数据类型的数字
长整型值:
duration 属性为动画持续时间
说明:
时间以毫秒为单位
-->
<alpha
android:duration="5000"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<!-- 渐变尺寸伸缩动画效果 -->
<!--
尺寸伸缩动画效果 scale
属性:interpolator 指定一个动画的插入器
试验过程中,使用android.res.anim中的资源时候发现
有三种动画插入器:
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
其他的属于特定的动画效果
浮点型值:
fromXScale 属性为动画起始时 X坐标上的伸缩尺寸
toXScale 属性为动画结束时 X坐标上的伸缩尺寸
fromYScale 属性为动画起始时Y坐标上的伸缩尺寸
toYScale 属性为动画结束时Y坐标上的伸缩尺寸
说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明:
以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
布尔型值:
fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用
-->
<scale
android:duration="5000"
android:fillAfter="false"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.4"
android:toYScale="1.4" />
<!--
translate 位置转移动画效果
整型值:
fromXDelta 属性为动画起始时 X坐标上的位置
toXDelta 属性为动画结束时 X坐标上的位置
fromYDelta 属性为动画起始时 Y坐标上的位置
toYDelta 属性为动画结束时 Y坐标上的位置
注意:
没有指定fromXType toXType fromYType toYType 时候,
默认是以自己为相对参照物
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
-->
<translate
android:duration="5000"
android:fromXDelta="30"
android:fromYDelta="30"
android:toXDelta="-80"
android:toYDelta="300" />
<!--
rotate 旋转动画效果
属性:interpolator 指定一个动画的插入器
试验过程中,使用android.res.anim中的资源时候发现
有三种动画插入器:
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
其他的属于特定的动画效果
浮点数型值:
fromDegrees 属性为动画起始时物件的角度
toDegrees 属性为动画结束时物件旋转的角度 可以大于360度
说明:
当角度为负数——表示逆时针旋转
当角度为正数——表示顺时针旋转
(负数from——to正数:顺时针旋转)
(负数from——to负数:逆时针旋转)
(正数from——to正数:顺时针旋转)
(正数from——to负数:逆时针旋转)
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
说明: 以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
长整型值:
duration 属性为动画持续时间
说明: 时间以毫秒为单位
-->
<rotate
android:duration="5000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="0%"
android:pivotY="100%"
android:toDegrees="-600" />
</set>
②Java问价中引入
private Animation loadAnimation (Context context,int id){
//第一个参数Context为程序的上下文
//第二个参数id为动画XML文件的引用
Animation mtAnimation = AnimationUtils.loadAnimation(context, id);
return mtAnimation;
}
③Java控件使用。
iv = (ImageView) findViewById(R.id.iv);
Animation myAnimation;
myAnimation = loadAnimation(getApplicationContext(),R.anim.my_anim_alpha);
iv.startAnimation(myAnimation);
- Java代码实现
不用xml文件完全用Java代码实现,除了完全能够实现xml所有功能外,还可以实现动画的属性值的动态的调整。
实现流程:
①Java代码实现动作效果
private Animation javaAnimation(){
myAnimation_Alpha = new AlphaAnimation(0.1f, 1.0f);
myAnimation_Alpha.setDuration(5000);
//ScaleAnimation(float fromX, float toX, float fromY, float toY,
// int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数fromX为动画起始时 X坐标上的伸缩尺寸
//第二个参数toX为动画结束时 X坐标上的伸缩尺寸
//第三个参数fromY为动画起始时Y坐标上的伸缩尺寸
//第四个参数toY为动画结束时Y坐标上的伸缩尺寸
/*说明:
以上四种属性值
0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
*/
//第五个参数pivotXType为动画在X轴相对于物件位置类型
//第六个参数pivotXValue为动画相对于物件的X坐标的开始位置
//第七个参数pivotXType为动画在Y轴相对于物件位置类型
//第八个参数pivotYValue为动画相对于物件的Y坐标的开始位置
myAnimation_Scale = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
myAnimation_Scale.setDuration(5000);
//第一个参数fromXDelta为动画起始时 X坐标上的移动位置
//第二个参数toXDelta为动画结束时 X坐标上的移动位置
//第三个参数fromYDelta为动画起始时Y坐标上的移动位置
//第四个参数toYDelta为动画结束时Y坐标上的移动位置
myAnimation_Translate = new TranslateAnimation(30.0f, -80.f, 30.0f, 300.0f);
myAnimation_Translate.setDuration(5000);
//RotateAnimation(float fromDegrees, float toDegrees,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一个参数fromDegrees为动画起始时的旋转角度
//第二个参数toDegrees为动画旋转到的角度
//第三个参数pivotXType为动画在X轴相对于物件位置类型
//第四个参数pivotXValue为动画相对于物件的X坐标的开始位置
//第五个参数pivotXType为动画在Y轴相对于物件位置类型
//第六个参数pivotYValue为动画相对于物件的Y坐标的开始位置
myAnimation_Rotate=new RotateAnimation(0.0f, +350.0f,Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF, 1.0f);
myAnimation_Rotate.setDuration(5000);
myAnimation_Rotate.setFillAfter(true);//动画在播放结束时是否保持最终的状态
myAnimation_Rotate.setRepeatCount(2);//动画的重复次数
myAnimation_Rotate.setRepeatMode(Animation.RESTART);
return myAnimation_Rotate;
}
②与控件绑定
iv = (ImageView) findViewById(R.id.iv);
Animation myAnimation;
// myAnimation = loadAnimation(getApplicationContext(),R.anim.my_anim_alpha);
myAnimation = javaAnimation();
iv.startAnimation(myAnimation);
自定义View动画
除了补间动画提供的四种动画外,还可以自定义动画。
实现方法:
接下来参考《Android开发艺术探索》
- 派生一种新的动画只需继承Animation这个抽象类;
- 重写他的initialize和applyTransformation方法;在initialize方法中做初始化工作,在applyTransformation方法中进行相应的矩阵变换。
难点: 自定义View动画的过程主要通过矩阵变换的过程,矩阵变换!
ok,至此 简单的补间动画也学习了。
View动画的特许使用场景
View动画的四种形式,除了这四种形式外,View动画还可以在一些特许场景下使用,
- ViewGroup中可以控制子元素的出场效果;
- 在Activity中实现不同Activity之间的切换效果。
LayoutAnimation
LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,当他的子元素出场时都会具有这种动画效果。
这种效果常用语ListView上,他的每一个item都已一定的动画形式出现。
Activity的切换效果
Activity有默认的切换效果,但这个效果我们也可以自定义;
方法:
overridePendingTransition(int enterAnim,int eixtAnim);
在startActivity(Intent)或者finish()之后被调用才生效;
enterAnim——Activity被打开时所需要的动画资源ID;
eixtAnim —— Activity被暂停时所需要的动画资源ID;
public void clickMe(View view){
Intent intent = new Intent(getApplicationContext(),OtherAty.class);
startActivity(intent);
overridePendingTransition(R.anim.push_bottom_in, 0);
}
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="100%p"
android:duration="300"
/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="100%p"
android:toYDelta="0"
android:duration="300"/>
</set>
public void finishSelf(View view){
finish();
overridePendingTransition(0, R.anim.push_bottom_out);
}
Fragment也可以添加切换动画,通过FragmentTransaction中的setCustomAnimations()方法来添加切换动画。
ok,接下来,属性动画。