属性动画
**为什么会有属性动画?**android都已经有帧动画以及补间动画了.
和电视剧火隐忍者一样,后出来的佐助永远比鼬的戏份更多一样. - -,猪脚光环的原因让属性动画相比补间动画更有优势的地方是. 属性动画是真实的将某一个属性进行了操作.改变了属性的值.而补间动画只是改变了画面一样.
专业点来说的话,补间动画其实是不停的 调用了onDraw()方法将界面不停的重新绘制,而属性动画是将有get,set方法的属性值给修改了.可以在修改的属性上,继续操作.
看看代码和效果.相信你更加明白!!
补间动画的效果,图片没移动之前可以点击弹出吐司.但是图片移动之后在图片结束位置再点击图片,但是没有反应,我们在图片原来的地方点击发现居然有反应,这就是补间动画很诡异的地方.
属性动画的效果,图片没有移动钱,可以打印吐司,移动之后,在图片动画结束位置,我们点击图片发现还是可以是响应点击事件,这个说明图片是真的移动了!
这里吧效果代码粘贴出来,代码很简单.看完效果代码,我们再详细的讲解属性动画!
mainactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:layout_alignParentBottom="true"
android:src="@drawable/ball"
android:id="@+id/iv_2"
android:layout_width="80dp"
android:layout_height="70dp"/>
<ImageView
android:layout_toRightOf="@id/iv_2"
android:layout_alignParentBottom="true"
android:src="@drawable/ball"
android:id="@+id/iv_1"
android:layout_width="80dp"
android:layout_height="70dp"/>
<Button
android:layout_alignParentBottom="true"
android:layout_toRightOf="@id/iv_1"
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="补间"/>
<Button
android:layout_toRightOf="@id/btn_1"
android:layout_alignParentBottom="true"
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="属性"/>
</RelativeLayout>
MainActivity的代码
package objectanimator.com.example.gzh.objectanimator;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import static android.R.attr.x;
import static android.R.attr.y;
public class MainActivity
extends Activity
implements View.OnClickListener
{
private ImageView mIvProperty;
private ImageView mIvTweening;
private int mScreenHeight;
private int mScreenWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mIvProperty = (ImageView) findViewById(R.id.iv_1);
mIvTweening = (ImageView) findViewById(R.id.iv_2);
Button btnTweening = (Button) findViewById(R.id.btn_1);
Button btnProperty = (Button) findViewById(R.id.btn_2);
initScreen();
btnTweening.setOnClickListener(this);
mIvProperty.setOnClickListener(this);
mIvTweening.setOnClickListener(this);
btnProperty.setOnClickListener(this);
}
private void initScreen() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// 屏幕的宽度
mScreenWidth = dm.widthPixels;
//屏幕的高度
mScreenHeight = dm.heightPixels;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//补间动画按钮
case R.id.btn_1:
float x1 = mIvTweening.getX();
float y1 = mIvTweening.getY();
TranslateAnimation animation=new TranslateAnimation(x,x,0,-y);
animation.setDuration(3000);
animation.setFillAfter(true);
mIvTweening.startAnimation(animation);
break;
//属性动画按钮
case R.id.btn_2:
float y2 = mIvProperty.getY();
ObjectAnimator.ofFloat(mIvProperty,"translationY",0,-y2).setDuration(3000).start();
break;
//属性动画的图片
case R.id.iv_1:
Toast.makeText(this,"属性图片被点击了",Toast.LENGTH_SHORT).show();
break;
//补间动画的图片
case R.id.iv_2:
Toast.makeText(this,"图片被点击了",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
属性动画集的按顺序播放
效果:
MainActivity代码:
package objectanimator.com.example.gzh.objectanimator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity
extends Activity
implements View.OnClickListener
{
private ImageView mIvProperty;
private int mScreenHeight;
private int mScreenWidth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initScreen();
mIvProperty = (ImageView) findViewById(R.id.iv_1);
Button btnProperty = (Button) findViewById(R.id.btn_2);
mIvProperty.setOnClickListener(this);
btnProperty.setOnClickListener(this);
}
private void initScreen() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
// 屏幕的宽度
mScreenWidth = dm.widthPixels;
//屏幕的高度
mScreenHeight = dm.heightPixels;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//属性动画按钮
case R.id.btn_2:
float y2 = 657f;
float v1 = y2 / 4;
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mIvProperty,
"translationY",
0,
-v1);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mIvProperty,
"translationX",
0,
mScreenWidth - 80);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mIvProperty,
"translationY",
-v1,
-v1 * 2);
ObjectAnimator animator4 = ObjectAnimator.ofFloat(mIvProperty,
"translationX",
mScreenWidth - 80,
0);
ObjectAnimator animator5 = ObjectAnimator.ofFloat(mIvProperty,
"translationY",
-v1 * 2,
-v1 * 3);
ObjectAnimator animator6 = ObjectAnimator.ofFloat(mIvProperty,
"translationX",
0,
mScreenWidth - 80);
ObjectAnimator animator7 = ObjectAnimator.ofFloat(mIvProperty,
"translationY",
-v1 * 3,
-v1 * 4);
ObjectAnimator animator8 = ObjectAnimator.ofFloat(mIvProperty,
"translationX",
mScreenWidth - 80,
0);
AnimatorSet set=new AnimatorSet();
set.playSequentially(animator1,animator2,animator3,animator4,animator5,animator6,animator7,animator8);
set.setDuration(3000);
set.start();
// Toast.makeText(this,"属性图片被点击了"+mScreenWidth,Toast.LENGTH_SHORT).show();
break;
//属性动画的图片
case R.id.iv_1:
Toast.makeText(this,"属性图片被点击了",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
属性动画集不按顺序播放(同时播放)
效果如图所示:
MainActivirty代码如下:
AnimatorSet set=new AnimatorSet();
set.play(animator1).with(animator2); //动画1和2同时执行
set.play(animator3).with(animator4).after(animator2);//动画3和4同时执行在动画2之后
set.play(animator5).with(animator6).after(animator4);//动画5和6同时执行在动画4之后
set.play(animator7).with(animator8).after(animator6);//动画7和8同时执行在动画6之后
set.setDuration(3000);
set.start();
因为其他代码不变,只不过是修改了set动画集里面的代码,所以粘贴相对应的代码.
属性动画监听
场景:一般开发的时候splash界面的动画执行完成之后,会跳转到相应的界面,在这个时候,我们需要对动画进行监听,监听动画完成.下面就给大家介绍属性动画的监听.
AnimatorListenerAdapter这里是安卓提供给我们方便使用的,因为可以自己实现需要实现的功能,这里只需要监听动画完成,所以只实现了一个onAnimationEnd()方法,当然里面有很多的方法,需要你自己去试一试!
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mIvProperty,
"translationY",
0,-mIvProperty.getY()
);
AnimatorSet set=new AnimatorSet();
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
startActivity( new Intent(MainActivity.this,activty2.class));
}
});
set.play(animator1);
set.setDuration(3000);
set.start();
最后介绍一个比较好玩的方法就是
set.getStartDelay()方法,设置开始的延时时间,可以让动画在执行多个动画的时候,有间隔的感觉.
最后介绍ValueAnimator
这个类当然我们使用ObjectAnimator是继承的ValueAnimator.
后续再给大家详细讲解
总结一下objectAnimator的常用属性
常用方法:
常用插值器的图片: