动画分为视图动画和属性动画框架。
视图动画:
提供AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四种动画方式
提供动画合集AnimationSet,用于动画混合
缺点显著:不具备交互性,只能做普通的动画效果
优点:效率高、使用方便
属性动画框架:更加丰富的动画效果。
常见问题
视图动画和属性动画优缺点
视图动画的使用
属性动画的使用
ObjectAnimator、AnimatorSet、PropertyValuesHolder、ValueAnimator的作用
如何利用xml使用属性动画
动画事件有哪些?
布局动画是什么?
插值器Interpolators的作用
SVG是什么?
SVG和Bitmap的区别
如何在Android中使用SVG(VectorDrawable和VectorDrawable)?
常见问题
1-视图动画实例
1-布局
2-Activity
2-属性动画
1-实例
2-没有getset方法
3-PropertyValuesHolder
4-ValueAnimator
1-实例数字自动增加0100
5-动画监听
6-AnimationSet
7-在XML中使用属性动画
XML文件
从XML中加载animator
8-View直接使用animate
3-布局动画
4-Interpolators插值器
5-自定义动画
6-Android 5x SVG矢量动画机制
1-SVG是什么Scalable Vetor Graphics
2-SVG和Bitmap区别
3-SVG编辑器
4-Android中使用SVG
1-VectorDrawable实例
2-AnimatedVectorDrawable实例动画效果
5-SVG做简单动画
1-绘制初始两条线
2-动画效果ObjectAnimator
3-粘合静态矢量图和动态动画
4-使用
6-SVG轨迹动画
1-视图动画实例
展现4种动画效果
1-布局
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"
android:orientation="vertical"
android:layout_weight="3"
tools:context="com.example.administrator.featherdemos.Activity.AnimationSetActivity">
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1"
android:weightSum="2">
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/jide"
android:layout_weight="1"
android:layout_centerInParent="true"/>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/jide"
android:layout_weight="1"
android:layout_centerInParent="true"/>
android:layout_height="0dp"
android:orientation="horizontal"
android:layout_weight="1"
android:weightSum="2">
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/jide"
android:layout_weight="1"
android:layout_centerInParent="true"/>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/jide"
android:layout_weight="1"
android:layout_centerInParent="true"/>
android:layout_width="match_parent"
android:layout_height="0dp"
android:src="@drawable/jide"
android:layout_weight="1"
/>
2-Activity
public class AnimationSetActivity extends Activity {
ImageView imageView1;
ImageView imageView2;
ImageView imageView3;
ImageView imageView4;
ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation_set);
imageView1 = (ImageView) findViewById(R.id.animationset_imageview1);
imageView2 = (ImageView) findViewById(R.id.animationset_imageview2);
imageView3 = (ImageView) findViewById(R.id.animationset_imageview3);
imageView4 = (ImageView) findViewById(R.id.animationset_imageview4);
imageView = (ImageView) findViewById(R.id.animationset_set_imageview);
//透明度
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(2000);
imageView1.setAnimation(alphaAnimation);
//旋转
RotateAnimation rotateAnimation = new RotateAnimation(0, 10);
rotateAnimation.setDuration(2000);
imageView2.setAnimation(rotateAnimation);
//缩放
ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 1, 0.5f, 1);
scaleAnimation.setDuration(2000);
imageView3.setAnimation(scaleAnimation);
//平移
TranslateAnimation translateAnimation = new TranslateAnimation(0, 50, 0, 50);
translateAnimation.setDuration(2000);
imageView4.setAnimation(translateAnimation);
/*
* 动画集合,可以混合多种动画效果。
* */
AnimationSet animationSet = new AnimationSet(true);
animationSet.setDuration(3000);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
imageView.setAnimation(animationSet);
}
}
2-属性动画
Animator框架中最多的就是AnimatorSet和ObjectAnimator。ObjectAnimator控制一个对象的一个属性,将多个ObjectAnimator组合成AnimatorSet形成动画。
属性值
作用
translationX、translationY
控制View从左上角偏移的位置
rotation、rotationX、rotationY
控制View围绕支点做2D和3D旋转
scaleX、scaleY
围绕支点2D缩放
pivotX、pivotY
控制支点位置,默认为View中心
x、y
描述View的最终位置
alpha
透明度,默认1不透明,0为完全透明
要操作的View的属性,必须要有get和set方法。
如果没有get、set方法,需要使用装饰者模式包装获得get、set;或者通过后面的ValueAnimator实现。
1-实例
ImageView imageView = (ImageView) findViewById(R.id.animator_imageview);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
"translationY", 300);
objectAnimator.setDuration(2000);
objectAnimator.start();
2-没有get、set方法
实现包装类
private class WrapperView{
private View view;
public WrapperView(View view){
this.view = view;
}
public int getWidth(){
return view.getLayoutParams().width;
}
public void setWidth(int width){
view.getLayoutParams().width = width;
view.requestLayout();
}
}
使用包装类实现属性动画
WrapperView wrapperView = new WrapperView(imageView);
ObjectAnimator.ofInt(wrapperView, "width", 500).setDuration(2000).start();
3-PropertyValuesHolder
类似于AnimationSet的作用,将多种效果共同作用于对象。
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationY", 200);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder(imageView, pvh1, pvh2, pvh3).setDuration(1000).start();
4-ValueAnimator
ObjectAnimator的父类,提供数值变化和监听,本身不完成动画,通过得到的数值可以去进行一定变换。
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100);
valueAnimator.setTarget(imageView);
valueAnimator.setDuration(1000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Float value = (Float) valueAnimator.getAnimatedValue();
//使用数值去完成数值的变换
}
});
1-实例:数字自动增加(0~100)
TextView textView = (TextView) findViewById(R.id.count_textview);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//数值动画从0~100增长
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
//使用获取的数值,显示在TextView(数值自动增长)
textView.setText((Integer) valueAnimator.getAnimatedValue()+"");
}
});
//动画在3s内完成
valueAnimator.setDuration(3000);
valueAnimator.start();
}
});
5-动画监听
有start、repeat、end、cancel四个过程,可以监听。
//监听全部步骤
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
//选择性监听
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
6-AnimationSet
可以和PropertyValuesHolder将动画融合,在此基础上还可以控制动画的顺序。
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView,"translationY", 300);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView,"scaleX", 1f, 0, 1f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(objectAnimator1, objectAnimator2);
animatorSet.setDuration(2000);
animatorSet.start();
7-在XML中使用属性动画
需要在res文件夹中创建animator文件夹!!
XML文件
在X轴上缩放,从1.0>0.5
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="0.5"
android:valueType="floatType">
从XML中加载animator
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.scalex);
animator.setTarget(imageView);
animator.start();
8-View直接使用animate()
是属性动画的一种简写形式。
imageView.animate() //获得animator
.alpha(0)
.y(300)
.setDuration(3000)
.withStartAction(new Runnable() {
@Override
public void run() {
}
})
.withEndAction(new Runnable() {
@Override
public void run() {
//结束动作后,在UI线程操作
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
})
.start(); //开始
3-布局动画
通过给ViewGroup设置布局动画,达到View逐渐呈现的过渡效果。
android:animateLayoutChanges="true"者可以给布局添加系统默认的效果。
如果要自定义过渡效果,需要通过LayoutAnimationController类来自定义,本质是给布局一个视图动画,在View出现时产生过渡效果。
LinearLayout mLinear = (LinearLayout) findViewById(R.id.mLinear);
//设置过渡动画
ScaleAnimation sa = new ScaleAnimation(0,1,0,1);
sa.setDuration(1000);
//设置布局动画的显示属性
//第一个参数,是需要作用的动画,而第二个参数,则是每个子View显示的delay时间
LayoutAnimationController lac = new LayoutAnimationController(sa,0.5f); lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
//为ViewGroup设置布局动画
mLinear.setLayoutAnimation(lac);
当delay的时间不为0时,可以设置子View显示的顺序:
LayoutAnimationController.ORDER_NORMAL——顺序
LayoutAnimationController.ORDER_RANDOM——随机
LayoutAnimationController.ORDER_REVERSE——反序
4-Interpolators(插值器)
插值器可以定义动画的变换速率。可以直接把插值器理解为动画变换的加速度。例如一个位移动画,如果使用线性插值器,那么在持续时间内,单位时间所移动的距离都是一样的;如果使用加速度插值器,那么单位时间内所移动的距离将越来越快。
Interpolator属性实际上是Animation类的一个XML属性,有很多系统值。
转载-Interpolator详细讲解
5-自定义动画
具体内容参考原著或者网上博客。
转载:复杂自定义动画实现
6-Android 5.x SVG矢量动画机制
1-SVG是什么?(Scalable Vetor Graphics)
可伸缩矢量图
定义用于网络的基于矢量的图形
使用XML格式定义图形
图像缩放不会影响质量
万维网联盟标准
与DOM和XSL之类的W3C标准是一个整体
2-SVG和Bitmap区别
Bitmap是通过每个像素点上存储色彩信息来表示图像。
SCG是一个绘图标准。
Bitmap放大不会失真。Bitmap需要为不同分辨率设计多套图表,SVG不需要。
3-SVG编辑器
SVG写法固定复杂,可以通过SVG编辑器完成。将图形编辑好后,可以使用编辑器转换为SVG代码。
4-Android中使用SVG
VectorDrawable:创建基于XML的SVG图形
AnimatedVectorDrawable:实现动画效果
1-VectorDrawable实例
在res右击,选择最上面的New,选择Vector Asset。
使用系统默认矢量图或者阿里矢量图库下载的矢量图。
创建好后ic_cake_black_24dp.xml如下:(我用系统默认图标)
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
android:pathData="M12,6c1.11,0 2,-0.9 2,-2 0,-0.38 -0.1,-0.73 -0.29,-1.03L12,0l-1.71,2.97c-0.19,0.3 -0.29,0.65 -0.29,1.03 0,1.1 0.9,2 2,2zM16.6,15.99l-1.07,-1.07 -1.08,1.07c-1.3,1.3 -3.58,1.31 -4.89,0l-1.07,-1.07 -1.09,1.07C6.75,16.64 5.88,17 4.96,17c-0.73,0 -1.4,-0.23 -1.96,-0.61L3,21c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1v-4.61c-0.56,0.38 -1.23,0.61 -1.96,0.61 -0.92,0 -1.79,-0.36 -2.44,-1.01zM18,9h-5L13,7h-2v2L6,9c-1.66,0 -3,1.34 -3,3v1.54c0,1.08 0.88,1.96 1.96,1.96 0.52,0 1.02,-0.2 1.38,-0.57l2.14,-2.13 2.13,2.13c0.74,0.74 2.03,0.74 2.77,0l2.14,-2.13 2.13,2.13c0.37,0.37 0.86,0.57 1.38,0.57 1.08,0 1.96,-0.88 1.96,-1.96L20.99,12C21,10.34 19.66,9 18,9z"/>
使用矢量图:
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@drawable/ic_cake_black_24dp"/>
2-AnimatedVectorDrawable实例:动画效果
创建animated-vector标签的文件ic_cake_anim_vector:
android:drawable="@drawable/ic_cake_black_24dp">
android:name="test">
android:drawable需要使用矢量图
android:animation中为objectAnimator的动画效果
android:name为矢量图中(在上个实例里)
布局中引用:
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@drawable/ic_cake_anim_vector"/>
开启动画:
ImageView imageView = (ImageView) findViewById(R.id.svg_anim_imageview);
((Animatable)imageView.getDrawable()).start();
AnimatedVectorDrawable将静态的VectorDrawable和动态的ObjectAnimator连接起来。
5-SVG做简单动画
将一个横线从中间折断变成“X”的效果
1-绘制初始两条线
vector_two_line.xml
android:width="200dp"
android:height="200dp"
android:viewportWidth="100"
android:viewportHeight="100">
android:pathData="M 20,80 L 50,80 80,80"
android:strokeColor="@color/colorAccent"
android:strokeWidth="3"
android:strokeLineCap="round"/>
android:pathData="M 20,20 L 50,20 80,20"
android:strokeColor="@color/colorAccent"
android:strokeWidth="3"
android:strokeLineCap="round"/>
2-动画效果(ObjectAnimator)
path1_animator:
android:duration="200"
android:propertyName="pathData"
android:valueFrom="M 20,80 L 50,80 80,80"
android:valueTo="M 20,80 L 50,50 80,80"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
path2_animator:
android:duration="200"
android:propertyName="pathData"
android:valueFrom="M 20,20 L 50,20 80,20"
android:valueTo="M 20,20 L 50,50 80,20"
android:valueType="pathType"
android:interpolator="@android:anim/bounce_interpolator">
3-粘合静态矢量图和动态动画
vector_two_line_anim.xml
android:drawable="@drawable/vector_two_line">
android:name="path1">
android:name="path2">
4-使用
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/vector_two_line_anim"/>
ImageView imageView = (ImageView) findViewById(R.id.two_line_imageview);
((Animatable)imageView.getDrawable()).start();
6-SVG:轨迹动画
轨迹动画,这里给上例的两条线在绘制的时候显示轨迹。
动画:
android:duration="1000"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:interpolator="@android:interpolator/accelerate_decelerate">
动画粘贴器:
android:drawable="@drawable/vector_two_line">
android:name="path1">
android:name="path2">
ImageView:
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="@drawable/vector_trimpath_anim"/>
使用:
ImageView imageView = (ImageView) findViewById(R.id.trimpath_anim_imageview);
((Animatable)imageView.getDrawable()).start();
这里省略了一些书上的实例,可以自行查阅。大致关于Android动画机制的内容就这么多了,还需要以后深入学习!