基础知识:
动画通过连续播放一系列画面,给视觉造成连续变化的图画。很通俗的一种解释。也很好理解。那么我们先来一个案例看看。
动画案例:百度贴吧小熊奔跑
效果:
AnimationDrawable
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/gif_loading1" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading2" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading3" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading4" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading5" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading6" android:duration="50"></item>
<item android:drawable="@drawable/gif_loading7" android:duration="50"></item>
</animation-list>
Java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_topic);
ImageView iv_topic = (ImageView) findViewById(R.id.iv_topic);
iv_topic.setBackgroundResource(R.drawable.anim_topic);
iv_topicAnimation = (AnimationDrawable) iv_topic.getBackground();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
iv_topicAnimation.start();
}
public static void startActiivty(Context context) {
context.startActivity(new Intent(context, TopicActivity.class));
}
可以看到,实现小熊奔跑的效果是非常简单的。你需要理解的是
1.小熊奔跑的效果是有一张张图片交替播放,而动起来的。
2.动画通过连续播放一系列画面,给视觉造成连续变化的图画。
以上只是简单介绍下动画的用法,下面才是真正的介绍Android动画了。
Android动画:
- 逐帧动画(frame-by-frame animation)
- 补间动画(tweened animation)
- 属性动画(property animation)
对于逐帧动画和补间动画这里就不打算具体深入,但是你必须要知道的
- 补间动画,只是改变View的显示效果而已,并不会真正的改变View的属性
- 补间动画,只作用于View上面
写了个demo来解释一下上面的意思:
bt_tween.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 300);
animation.setDuration(1000);
animation.setFillAfter(true);
tv_tween_hello.startAnimation(animation);
}
});
tv_tween_hello.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(context,"hello animation",Toast.LENGTH_SHORT).show();
}
});
可以看到其实hello Animation平移之后点击没用了,而点击之前的位置的时候,还是有效的。这也正是我刚才说的
补间动画:只是改变View的显示效果而已,并不会真正的改变View的属性
看到这里,你也知道如果要用补间动画来做一些交互的动画是很蛋疼的。一般做法是:
- 预先在动画结束的地方设置一个不可见的View,然后动画结束之后,让其显示。这样就可以处理事件。
- 利用https://github.com/JakeWharton/NineOldAndroids
属性动画
在介绍属性动画前,我们还是先来看一个demo。
protected Person person;
protected TextView tv_property_info;
protected Button bt_property;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
person = new Person();
person.setName("张三");
bt_property = (Button) findViewById(R.id.bt_property);
tv_property_info = (TextView) findViewById(R.id.tv_property_info);
bt_property.setOnClickListener(this);
}
@Override
public void onClick(View v) {
ObjectAnimator objectAnimator = ObjectAnimator.ofInt(person, "age", 1, 100);
objectAnimator.addUpdateListener(this);
objectAnimator.setDuration(5000);
objectAnimator.start();
}
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int values = (int) animation.getAnimatedValue();
person.setAge(values);
tv_property_info.setText(person.toString());
}
上面代码模拟了一个Person对象,从0-100岁之间的变化,可能你有点看不懂。我这是在干嘛,但是如果你还记的刚才我说的。属性动画,可以对任何对象属性进行修改,而补间动画,只作用于View上面。我们的demo就是对Person这个对象中属性age不断进行修改。现在,我们假设一个TextView要进行平移或则缩放,或则旋转。只要将对应的属性进行修改,然后重绘。不就可以达到动画的效果了吗?试试吧!
protected TextView tv_property_info;
protected Button bt_property;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_property);
bt_property = (Button) findViewById(R.id.bt_property);
bt_property.setText("View的改变");
tv_property_info = (TextView) findViewById(R.id.tv_property_info);
bt_property.setOnClickListener(this);
}
@Override
public void onClick(View v) {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv_property_info, "TranslationY", 0, 300);
objectAnimator.addUpdateListener(this);
objectAnimator.setDuration(500);
objectAnimator.start();
}
我们来总结一下.当我们调用
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv_property_info, "TranslationY", 0, 300);
objectAnimator.setDuration(500);
的时候,将初始值和结束值给ObjectAnimator,并且告诉它所需的时长,然后它的内部使用一种时间循环的机制来计算值与值之间的过渡。然后将变化的值返回给我们。然后我们获取这个间隙的值,重绘界面就给视觉造成连续变化的图画。