属性动画

转载请注明出处:http://blog.csdn.net/wei_chong_chong/article/details/50820558


这次我们来学习一下属性动画

这里你可以学到:

实现Animation框架的功能

属性动画常用属性

动画的监听事件


这里我采用逐步优化的方式学习使用属性动画的各种操作(你可以对比各种方法的优缺点)

属性动画改变的是对象的属性,只要对象某个的属性有get和setf方法就可以对这个属性进行属性动画

先看一个简单的例子吧:

这里我在布局文件中添加了一个ImageView的控件和一个Button控件

我对ImageView添加动画效果

点击Button按钮显示动画效果

public class MainActivity extends Activity {

	private Button mbutton ;
	private ImageView mImageView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mbutton = (Button) findViewById(R.id.start);
		mImageView = (ImageView) findViewById(R.id.mImageView);
		mbutton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//参数含义1.操作的对象  2.Y轴平移的偏离量属性3.初始位置 4.移动后的位置
				//setDuration(1000)是移动的时间
				ObjectAnimator.ofFloat(mImageView, "translationY", 0F,500F).setDuration(3000).start(); 
				//X轴平移
				ObjectAnimator.ofFloat(mImageView,"translationX",0,500F).setDuration(3000).start();
				//旋转360度
				ObjectAnimator.ofFloat(mImageView,"rotation",0,360F).setDuration(3000).start();


			}
		});
	}
}


ObjectAnimator.ofFloat(mImageView, "translationY", 100F,500F).setDuration(1000).start(); 
//参数含义1.操作的对象  2.Y轴平移的属性 3.初始位置 4.移动后的位置

属性动画的移动是异步进行的,

//setDuration(1000)是移动的时间


多种属性动画效果同时进行:

方法一:

ObjectAnimator.ofFloat(mImageView, "translationY", 0F,500F).setDuration(3000).start(); 
				//X轴平移
				ObjectAnimator.ofFloat(mImageView,"translationX",0,500F).setDuration(3000).start();
				//旋转360度
				ObjectAnimator.ofFloat(mImageView,"rotation",0,360F).setDuration(3000).start();

优化:谷歌对多个属性动画同时运行进行了性能上的优化,即使用PropertyValuesHolder类控制,使占用更少的系统资源,如下所示

方法二

	PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0,360F);
				PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationX",0,500F);
				PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat( "translationY", 0F,500F);

				ObjectAnimator.ofPropertyValuesHolder(mImageView,p1,p2,p3).setDuration(3000).start();

为了使动画有更丰富的效果可以使用动画集合

方法三

ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView, "translationY", 0F,500F);
				ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView,"translationX",0,500F);
				ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView,"rotation",0,360F);
				AnimatorSet set = new AnimatorSet();
				set.playTogether(animator1,animator2,animator3);
				set.setDuration(3000);
				set.start();

更丰富的效果:

效果一:按顺序执行动画先Y轴平移,然后X轴平移,最后旋转

使用集合的set.playSequentially(animator1,animator2,animator3);方法就行了

set.playTogether(animator1,animator2,animator3);//同时进行
set.playSequentially(animator1,animator2,animator3);//依次进行

效果二:X,Y轴平移同时进行,执行完之后再旋转

	set.play(animator1).with(animator2);
	set.play(animator3).after(animator2);//或者<span style="white-space:pre">	</span>set.play(animator3).with(animator1);
<span style="white-space:pre">				</span>

今天先写这么多吧。不知道为啥在我的真机(魅蓝note)上模拟不出来效果,单是在其他真机上可以,可能魅族手机对动画做了处理吧


继续学习,动画的监听事件

在布局文件中添加一个按钮Button

在主函数中添加点击事件

public void click(View view){
		// TODO Auto-generated method stub
		Toast.makeText(this, view.getId(), 1);
		//透敏度变化
		ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0F,1F);
		animator.setDuration(1000);//动画时长
		//给动画添加监听事件


		animator.start();


	}
这里闹了个笑话,我开始把click方法设置成private的了,点击一直报错,后来发现,必须声明成public 的,大家注意一下!!

//给动画添加监听事件
		animator.addListener(new AnimatorListener() {

			@Override
			public void onAnimationStart(Animator animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationRepeat(Animator animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationEnd(Animator animation) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onAnimationCancel(Animator animation) {
				// TODO Auto-generated method stub

			}
		});

因为不需要实现所有的方法,一般只使用实现动画完成后的方法所以,这里Android有一个适配器帮我们解决了这个问题

animator.addListener(new AnimatorListenerAdapter() {
			@Override
			public void onAnimationEnd(Animator animation) {
				// TODO Auto-generated method stub
				super.onAnimationEnd(animation);
			}
		});

下面实现一个按钮弹出的效果:

里面是重叠的大小相同的几个圆形按钮

主界面布局文件xml代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.objectanimatortext1.MainActivity" >

 

    <ImageView
        android:id="@+id/image_h"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/h" />

    <ImageView
        android:id="@+id/image_g"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/g" />

    <ImageView
        android:id="@+id/image_f"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/f" />

    <ImageView
        android:id="@+id/image_e"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/e" />

    <ImageView
        android:id="@+id/image_d"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/d" />

    <ImageView
        android:id="@+id/image_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/c" />

    <ImageView
        android:id="@+id/image_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/b" />

    <ImageView
        android:id="@+id/image_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:paddingTop="5dp"
        android:src="@drawable/a" />

</FrameLayout>

在MainActivity:

public class MainActivity extends Activity implements OnClickListener{
	private int[] resid = {R.id.image_a,R.id.image_b,R.id.image_c,R.id.image_d,R.id.image_e,R.id.image_f,R.id.image_g,R.id.image_h};

	private List<ImageView> imageViewList = new ArrayList<ImageView>();


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		for (int i = 0; i < resid.length; i++) {
			ImageView imageView = (ImageView) findViewById(resid[i]);
			imageView.setOnClickListener(this);
			imageViewList.add(imageView);
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		int myid = v.getId();
		if(myid == R.id.image_a){
			startAnim();
		}else {	

		}
	}
	private void startAnim(){
		for(int i = 0;i < resid.length;i++){
			ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", 0F,i*100);
<span style="white-space:pre">			</span>animator.setDuration(500);
			animator.start();
		}
	}
}
代码中是设置Y轴动画平移:

ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", 0F,i*100);
<span style="white-space:pre">			</span>animator.setDuration(500);
			animator.start();

继续优化:

达到依次弹出的效果:

实现方法:加入动画启动延迟效果

animator.setStartDelay(i * 300);

修改startAnim()方法

private void startAnim(){
		for(int i = 0;i < resid.length;i++){
			ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", 0F,i*100);
			animator.setDuration(500);
			animator.setStartDelay(i * 300);
			animator.start();
		}
	}

下面添加回收事件,实现点击一下打开,再点击一下关闭菜单的效果

private void closeMenu(){
		for(int i = 0;i < resid.length;i++){
			ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", i*100,0F);
			animator.setDuration(500);
			animator.setStartDelay(i * 300);
			animator.start();
			isOpen = false;
		}
	}

完整代码:

public class MainActivity extends Activity implements OnClickListener{
	private boolean isOpen;
	private int[] resid = {R.id.image_a,R.id.image_b,R.id.image_c,R.id.image_d,R.id.image_e,R.id.image_f,R.id.image_g,R.id.image_h};

	private List<ImageView> imageViewList = new ArrayList<ImageView>();


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		for (int i = 0; i < resid.length; i++) {
			ImageView imageView = (ImageView) findViewById(resid[i]);
			imageView.setOnClickListener(this);
			imageViewList.add(imageView);
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		int myid = v.getId();
		if(myid == R.id.image_a){
			toogle();
		}else {	

		}
	}
	private void openMenu(){
		for(int i = 0;i < resid.length;i++){
			ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", 0F,i*100);
			animator.setDuration(500);
			animator.setStartDelay(i * 300);
			animator.start();
			isOpen = true;
		}
	}
	private void closeMenu(){
		for(int i = 0;i < resid.length;i++){
			ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i),
					"translationY", i*100,0F);
			animator.setDuration(500);
			animator.setStartDelay(i * 300);
			animator.start();
			isOpen = false;
		}
	}
	private void toogle(){
		if(isOpen){
			closeMenu();
		}else {
			openMenu();

		}
	}
}

下面继续优化:

让菜单动画弹出时轨迹不是线性的,更灵活

这里用到一个术语:插值器

android内置9中插值器

下面加入自由落体插值器

使用方法就是在animator.start()之前调用

animator.setInterpolator(new BounceInterpolator());//自由落体插值器


下面学习ValueAnimator来实现更炫酷的动画效果

ValueAnimator是一个数值发生器,提供各种数值的计算方法,它本身作用于任何属性不能设置任何动画

ValueAnimator是ObjectAnimator的父类

下面使用ValueAnimator实现一个计时器效果

:有一个Button,点击之后,button中的内容由100依次减小到0

常规做法是使用线程,加for循环

这里我们使用动画来实现同样的效果

给按钮添加点击事件

	public void onClick(View view){
		final Button button = (Button) view;
		ValueAnimator animator = ValueAnimator.ofInt(0,100);//线性产生0到100的整数
		animator.setDuration(5000);
		animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
			//通过添加这个监听事件可以获取到ValueAnimator每一步产生的值
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// TODO Auto-generated method stub
				Integer value = (Integer) animation.getAnimatedValue();
				button.setText(""+value);
			}
		});
	}

下面来实现自定义的数值数值生成器

这一点我学的也不好,这里就不再说了。

总结:

常用属性:

translationX/translationY  X,Y轴平移

rotainon,rotationX,rotationY  3D旋转动画

scaleX,scaleY缩放动画

X,Y移动到某个具体的点

alpha透明度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值