Android动画
基础知识:
动画通过连续播放一系列画面,给视觉造成连续变化的图画。很通俗的一种解释。也很好理解。那么我们先来一个案例看看。
动画案例:百度贴吧小熊奔跑
效果:
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,并且告诉它所需的时长,然后它的内部使用一种时间循环的机制来计算值与值之间的过渡。然后将变化的值返回给我们。然后我们获取这个间隙的值,重绘界面就给视觉造成连续变化的图画。