前言:不要让别人的无知断送了你的梦想,永远坚信你所坚信的。
相关文章:
《Android自定义控件三部曲文章索引》:http://blog.csdn.net/harvic880925/article/details/50995268
一、概述
long long ago,我写过几篇有关Animation的文章,讲解了传统的alpha、scale、translate、rotate的用法及代码生成方法。其实这三篇文章讲的所有动画效果叫做Tween Animation(补间动画)
在Android动画中,总共有两种类型的动画View Animation(视图动画)和Property Animator(属性动画);
其中
- View Animation包括Tween Animation(补间动画)和Frame Animation(逐帧动画);
- Property Animator包括ValueAnimator和ObjectAnimation;
首先,直观上,他们有如下三点不同:
1、引入时间不同:View Animation是API Level 1就引入的。Property Animation是API Level 11引入的,即Android 3.0才开始有Property Animation相关的API。
2、所在包名不同:View Animation在包android.view.animation中。而Property Animation API在包 android.animation中。
3、动画类的命名不同:View Animation中动画类取名都叫XXXXAnimation,而在Property Animator中动画类的取名则叫XXXXAnimator
大家都知道逐帧动画主要是用来实现动画的,而补间动画才能实现控件的渐入渐出、移动、旋转和缩放的;而Property Animator是在Android 3.0版本才引入的,之前是没有的。大家可能会觉得补间动画和逐帧动画已经很全了,为什么还要引入Property Animator呢?
1、为什么引入Property Animator(属性动画)
我提出一个假设:请问大家,如何利用补间动画来将一个控件的背景色在一分钟内从绿色变为红色?这个效果想必没办法仅仅通过改变控件的渐入渐出、移动、旋转和缩放来实现吧,而这个效果是可以通过Property Animator完美实现的
这就是第一个原因:Property Animator能实现补间动画无法实现的功能
大家都知道,补间动画和逐帧动画统称为View Animation,也就是说这两个动画只能对派生自View的控件实例起作用;而Property Animator则不同,从名字中可以看出属性动画,应该是作用于控件属性的!正因为属性动画能够只针对控件的某一个属性来做动画,所以也就造就了他能单独改变控件的某一个属性的值!比如颜色!这就是Property Animator能实现补间动画无法实现的功能的最重要原因。
我们得到了第二点不同:View Animation仅能对指定的控件做动画,而Property Animator是通过改变控件某一属性值来做动画的。
假设我们将一个按钮从左上角利用补间动画将其移动到右下角,在移动过程中和移动后,这个按钮都是不会响应点击事件的。这是为什么呢?因为补间动画仅仅转变的是控件的显示位置而已,并没有改变控件本身的值。View Animation的动画实现是通过其Parent View实现的,在View被drawn时Parents View改变它的绘制参数,这样虽然View的大小或旋转角度等改变了,但View的实际属性没变,所以有效区域还是应用动画之前的区域;我们看到的效果仅仅是系统作用在按钮上的显示效果,利用动画把按钮从原来的位置移到了右下角,但按钮内部的任何值是没有变化的,所以按钮所捕捉的点击区域仍是原来的点击区域。(下面会举例来说明这个问题)
这就得到了第三点不同:补间动画虽能对控件做动画,但并没有改变控件内部的属性值。而Property Animator则是恰恰相反,Property Animator是通过改变控件内部的属性值来达到动画效果的
2、举例说明补间动画的点击区域问题
下面我们就利用TranslateAnimation来做一个移动动画的例子,看它的点击区域是否会变。
我们先来看看效果:
在效果图中,首先,我给textview添加了点击响应,当点击textview时,会弹出Toast。
然后,当我点击按钮的时候,textview开始向右下角移动。
从结果中可以看出,在移动前,点击textview是可以弹出toast的的,在移动后,点击textview时则没有响应,相反,点击textview的原来所在区域则会弹出toast.
这就论证了不同第三点:补间动画虽能对控件做动画,但并没有改变控件内部的属性值
下面简单看看这个动画的实现代码吧:
(1)、看布局(main.xml)
从效果图中也可以看出,布局很简单,一个button,一个textview,垂直排列,布局代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="start anim"
/>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#ffff00"
android:text="Hello qijian"/>
</LinearLayout>
(2)JAVA代码(MyActivity.java)
接下来是操作代码,就是分别给button和textview添加上点击响应,当点击textview时弹出toast,点击button时,textview使用移动。
代码如下:
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final TextView tv = (TextView) findViewById(R.id.tv);
Button btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final TranslateAnimation animation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 400,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 400);
animation.setFillAfter(true);
animation.setDuration(1000);
tv.startAnimation(animation);
}
});
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MyActivity.this,"clicked me",Toast.LENGTH_SHORT).show();
}
});
}
}
这段代码很容易理解,这里就不再细讲了。
<