Android属性动画应用

 1. 动画实现例子,理解     

补间动画问题:
     1. 动画假象,移动到目标位置以后,控件还在原来地方,原来地方可设置点击事件
     属性动画是真实改变动画属性
 一个最简单的移动图片移动例子:

ImageView shuxingImg;
	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pro_perty);
		shuxingImg= (ImageView)findViewById(R.id.shuxingImg);
	}
	 // Button控件 点击效果
	 	public void pingyi(final  View view){
		// 什么是动画,动画就是在指定时间内不断改变空间位置
		// 最简单的移动例子
		new Thread(){
			@Override
			public void run() {
				super.run();
				for (int i=0;i<100;i++){
					SystemClock.sleep(100);
					runOnUiThread(new Runnable() {
						@Override
						public void run() {
							int left = shuxingImg.getLeft();
							int top = shuxingImg.getTop();
							int right= shuxingImg.getRight();
							int bottom = shuxingImg.getBottom();
							shuxingImg.layout(left+5,top+5,right+5,bottom+5);
						}
					});
				}
			}
		}.start();

 效果图:

2. Android属性动画 

*******************************************************     
   Android为了方便,提供属性动画Api  可以控制属性:
  1. translationX
   translationY:  控制View控制,坐标原点相对于左上角(0,0)的一个偏移量
   shuxingImg.animate().translationXBy(shuxingImg.getWidth())
   x、y 描述的左上角坐标的偏移量 原来位置加上+
   
  2. rotation  rotationX 和 rotationY, 控制View绕着 (pivoX 和 pivoY) 旋转
   
  3. scaleX和 scaleY  控制View绕着 (pivoX 和 pivoY) 缩放
    (pivoX 和 pivoY) 是 View的中心点
    
  4. alpha 不透明度   1 不透明   0透明
  
  API实现:
          shuxingImg.animate()
                     .translationXBy(shuxingImg.getWidth())
                     .translationYBy(shuxingImg.getHeight())
                .alpha(0)
                     .setDuration(2000)
                     .setInterpolator(new BounceInterpolator())   
                     .start();
                     
*******************************************************    

属性动画写法1    animate():

// 实现 X轴移动图片 宽度、Y轴移动 图片高度,隐藏图片,在2000 毫秒内
ImageView shuxingImg;
	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pro_perty);
		shuxingImg= (ImageView)findViewById(R.id.shuxingImg);
	}
		@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@SuppressLint("NewApi")
	public void pingyi(final  View view){
	//	      //另外一种写法
		shuxingImg.animate()
	                 .translationXBy(shuxingImg.getWidth())
	                 .translationYBy(shuxingImg.getHeight())
				.alpha(0)
	                 .setDuration(2000)
	                 .setInterpolator(new BounceInterpolator())
	                 .start();
					 }

 总结: ObjectAnimator和   AnimatorSet 使用  同时执行多个动画
或者:addUpdateListener 监听 shuxingImg.setAlpha(1-x0) 设置属性,也可以设置多个动画同时执行
2.  ObjectAnimator和   playSequentially 使用  同时依次执行 实现属性动画

  	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@SuppressLint("NewApi")
	public void pingyi(final  View view){
		// 0 实现 现对于控件 左上 角坐标
		//  X 轴 移动累加  距离shuxingImg.getWidth()
		 ObjectAnimator animator3 = ObjectAnimator.ofFloat(shuxingImg,"translationX",0,shuxingImg.getWidth());
        animator3.setDuration(2000);

        animator3.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				// 动画执行过程不断调用该方法
				float x0=animation.getAnimatedFraction(); //动画执行百分比  0-1
				float x1= (float) animation.getAnimatedValue();  // 动画执行0-shuxingImg.getWidth() 中的某一个值
				float t1=  animation.getCurrentPlayTime();   //动画已经执行毫秒数据
				Log.e("denganzhi1","百分比:"+x0+"  移动距离:"+x1 +" 已经执行时间:"+t1);

				// 设置动画透明度
			//	shuxingImg.setAlpha(1-x0);

			}
		});
        // 动画开始,结束,取消,暂停,重新启动
        animator3.addListener(new AnimatorListenerAdapter() {
			@Override
			public void onAnimationCancel(Animator animation) {
				super.onAnimationCancel(animation);
			}

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
			}

			@Override
			public void onAnimationRepeat(Animator animation) {
				super.onAnimationRepeat(animation);
			}

			@Override
			public void onAnimationStart(Animator animation) {
				super.onAnimationStart(animation);
			}

			@Override
			public void onAnimationPause(Animator animation) {
				super.onAnimationPause(animation);
			}

			@Override
			public void onAnimationResume(Animator animation) {
				super.onAnimationResume(animation);
			}
		});

		//  Y 轴 移动累加  距离shuxingImg.getHeight()
	     ObjectAnimator animator4 = ObjectAnimator.ofFloat(shuxingImg,"translationY",0,shuxingImg.getHeight());
	

	//实现多个同时执行
  	//	animator3.setStartDelay(3000); // 虽然是同时执行,但是可以设置延时
	     AnimatorSet set = new AnimatorSet();
//	        set.playTogether(animator3,animator4);
//	        set.setDuration(2000);
//	        set.setInterpolator(new BounceInterpolator());  //设置串改器,抖动效果
//	        set.start();


// 动画执行顺序控制使用 play 、with  
//  before after 
//		ObjectAnimator animator1 = ObjectAnimator.ofFloat(iv, "alpha", 1f,0f,1f);
//		ObjectAnimator animator2 = ObjectAnimator.ofFloat(iv, "scaleX", 1f,0.7f,1f);
//		ObjectAnimator animator3 = ObjectAnimator.ofFloat(iv, "scaleY", 1f,0.7f,1f);
//		AnimatorSet animatorSet = new AnimatorSet();
//		animatorSet.setDuration(2000);
//		//多个动画同时执行
		animatorSet.playTogether(animator1,animator2,animator3);
//		//也是多个动画同时执行--with通过with, playTogether底层就是调用with
//		animatorSet.play(animator2).with(animator3).with(animator1);
//		//A before B:A在B执行之前; A after B:A在B执行之后执行
//		animatorSet.play(animator2).with(animator3).before(animator1);
//		animatorSet.start();
 
// 实现多个动画依次执行
		   set.playSequentially(animator3,animator4);  
	    	set.start();
	}

 多个动画同时执行效果图:

 3. ValueAnimator 的使用 实现属性动画
        // 使用 ValueAnimator 设置属性动画 水平移动:
        // ValueAnimator 就是一个  计算器,在500 ms 内 从 0-100不断计算中间值

//  实现在500 毫秒内, 图片水平移动100 px功能
ImageView shuxingImg;
	@SuppressLint("NewApi")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_pro_perty);
		shuxingImg= (ImageView)findViewById(R.id.shuxingImg);
	}
		@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@SuppressLint("NewApi")
	public void pingyi(final  View view){
	   // 使用 ValueAnimator 设置属性动画 水平移动:
		// ValueAnimator 就是一个  计算器,在500 ms 内 从 0-100不断计算
		ValueAnimator mValueAnim = ValueAnimator.ofFloat(0, 100);
		// 动画监听
		mValueAnim.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator mAnim) {
				float fraction = mAnim.getAnimatedFraction();
				// percent 0.0 -> 1.0
				//Log.d(TAG, "fraction: " +fraction);
				//	Integer newHeight = evaluate(fraction, startHeight, endHeight);
				Float currentValue = (Float) mAnim.getAnimatedValue();
				shuxingImg.setX(shuxingImg.getLeft()+currentValue);
				Log.e("denganzhi1", "currentValue:"+currentValue+"");
				shuxingImg.requestLayout();
			}
		});

		//	mValueAnim.setInterpolator(new OvershootInterpolator()); //这里设置串改器,有抖动效果
		mValueAnim.setDuration(500);
		mValueAnim.start();
    }

4 使用 PropertyValuesHolder 实现属性动画,多个动画同时执行,实现属性动画

     ImageView shuxingImg;
    @SuppressLint("NewApi")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pro_perty);
        shuxingImg= (ImageView)findViewById(R.id.shuxingImg);
    }    
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @SuppressLint("NewApi")
    public void pingyi(final  View view){
             // 使用PropertyValuesHolder 设置属性动画
        // 缩放从原来1.0到0.7 恢复1.0
        PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleX", 1f,0.7f,1f);
        PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleY", 1f,0.7f,1f);
        //在原来基础上 X轴移动 300
        PropertyValuesHolder holder4 = PropertyValuesHolder.ofFloat("translationX", 0f,300f);
        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(shuxingImg, holder2,holder3,holder4);
        animator.setDuration(1000);
        animator.addUpdateListener(new AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // TODO Auto-generated method stub
                float animatedValue = (Float) animation.getAnimatedValue();  //默认的
                float animatedValueTranX=(Float) animation.getAnimatedValue("translationX");  //获取具体的值
                float animatedFraction = animation.getAnimatedFraction();
                long playTime = animation.getCurrentPlayTime();

                    Log.e("denganzhi","animatedValue:"+animatedValue+",  "
                            + "playTime:"+playTime+"animatedValueTranX:"+animatedValueTranX
                            +"animatedFraction:"+animatedFraction);

            //    System.out.println("animatedFraction:"+animatedFraction);
            }
        });
        animator.start();
    }

3.  属性动画自定义估值器 

 问题:
ValueAnimator mValueAnim = ValueAnimator.ofFloat(0, 100);
mValueAnim.addUpdateListener(new AnimatorUpdateListener() {
float fraction = mAnim.getAnimatedFraction();
                // percent 0.0 -> 1.0
                //Log.d(TAG, "fraction: " +fraction);
                //    Integer newHeight = evaluate(fraction, startHeight, endHeight);
                Float currentValue = (Float) mAnim.getAnimatedValue();
                shuxingImg.setX(shuxingImg.getLeft()+currentValue);
                Log.e("denganzhi1", "currentValue:"+currentValue+"");
}
mValueAnim.setDuration(500);
// 默认计算方式500毫秒内
// 0-100 匀速累加,
// 我现在的需要: 要实现抛物效果
// X 轴 按照 x= vt  来计算
// y 轴 按照 y= 1/2*g*t^2 来计算
// 那么需要自定义 setEvaluator 估值器,按照的方式来计算 变化量 

 实现代码:

  // 系统有哪些估值器:
              /// TypeEvaluator     设置类型估值器
              /// //ArgbEvaluator   颜色估值器
         // FloatEvaluator     Float估值器
         //PointEvaluator      Point估值器

 public void paowuxiangtest(View view){
		 /**
		  * // Android实现 抛物效果
		  // x= vt
		  // y= 1/2*g*t^2
		  */
		 ValueAnimator valueAnimator = new ValueAnimator();
		 valueAnimator.setDuration(4000);
		 float startX= shuxingImg.getX();
		 float startY= shuxingImg.getY();
		 Log.e("denganzhi1", "startX:"+startX+"stratY:"+startY);
		 //  起始点,指定坐标默认位置
		 valueAnimator.setObjectValues(new PointF(startX, startY));
		
//		 * x:匀速  x=vt
//		 * y:加速度   y=1/2*g*t*t
//		 * 使用估值器最好实现。
		 valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
			 			@Override
			 			public PointF evaluate(float fraction, PointF startValue,
			 					PointF endValue) {
			 				//startValue==? 不知道
			 				PointF pointF = new PointF();
			 				// 6为 执行时间
			 				pointF.x = endValue.x+100f*(fraction*6);//初始速度*(执行的百分比*4)
							// 9.8f效果太差了  换成3.0
			 				pointF.y = endValue.y+0.5f*30.0f*(fraction*6)*(fraction*6);
			 				
			 			//	pointF.y = 0.5f*150f*(fraction*4)*(fraction*4);
			 				return pointF;
			 			}
			 		});
		valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				//得到此时间点的坐标
				PointF pointF = (PointF) animation.getAnimatedValue();
				
				shuxingImg.setX(pointF.x);
				shuxingImg.setY(pointF.y);
			}
		});
		valueAnimator.start();
	 }

动画效果:

 // 系统提供插值器使用,这些都是根据设计美学来的
//https://blog.csdn.net/qq_38182125/article/details/89631460 参考 有具体图
	 // 系统提供插值器使用,这些都是根据设计美学来的
	//https://blog.csdn.net/qq_38182125/article/details/89631460 参考 有具体图
	 public void interpolatorTest(View view){
		 ObjectAnimator oa = ObjectAnimator.ofFloat(shuxingImg, "translationY", 0f,200f);
			oa.setDuration(500);
			//设置加速器---
//			oa.setInterpolator(new AccelerateInterpolator(5));
//			oa.setInterpolator(new AccelerateDecelerateInterpolator());
//			oa.setInterpolator(new AnticipateInterpolator(8));
//	      有一个回弹效果,例子,卫星菜单
			oa.setInterpolator(new OvershootInterpolator());
//			oa.setInterpolator(new CycleInterpolator(4));
		//	oa.setInterpolator(new BounceInterpolator());
			
			oa.start();
	 }

 效果图:setInterpolator 弹出在有点弹出来效果,图片弹回来的有点多,其实很少的

 4. Google MaterialDesign新动画效果:


  1.   触摸反馈
例子:水波纹效果  
  2.  揭露效果:
    例子:按钮揭露效果
  3.   曲线运动: 
  例子:花椒直播点赞飘出很多心心

Xml布局:

<LinearLayout 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"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    >
    <!--
     android 5.0 默认自带
      水波纹效果 覆盖父主题效果 直接到 DarkActionBar 中找即可
    <item name="colorControlHighlight">#FF0000</item >
    -->
    <Button
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:text="1.Android5.0揭露效果,水波纹" />

    <Button
        android:id="@+id/bt1"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:text="2. 5.0揭露效果,中心点揭露" />
    <Button
        android:id="@+id/bt2"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:text="3. 5.0揭露效果,右上角揭露" />

</LinearLayout>

Java 代码实现:

package com.atguigu.l10_animation;

import android.animation.Animator;
import android.annotation.TargetApi;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.animation.AccelerateInterpolator;
import android.widget.Button;

public class AndroidLActivity extends AppCompatActivity {
    private Button bt1;
    private Button bt2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_l);
        bt1 = (Button)findViewById(R.id.bt1);
        bt2 = (Button)findViewById(R.id.bt2);

        bt1.setOnClickListener(new View.OnClickListener() {
            @TargetApi(21)
            @Override
            public void onClick(View v) {
                //圆形水波纹揭露效果
//				ViewAnimationUtils.createCircularReveal(
//						view, //作用在哪个View上面
//						centerX, centerY, //扩散的中心点
//						startRadius, //开始扩散初始半径
//						endRadius)//扩散结束半径

                // 揭露中心点、揭露初始半径、揭露最终半径,这个是实心揭露
                Animator animator = ViewAnimationUtils.createCircularReveal(bt1, bt1.getWidth()/2, bt1.getHeight()/2, 0, bt1.getHeight());
                animator.setDuration(1000);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();
//				Math.hypot(x, y)
            }
        });
        bt2.setOnClickListener(new View.OnClickListener() {
            @TargetApi(21)
            @Override
            public void onClick(View v) {
                // 勾股定理:hypot, 最终半径用 勾股定理计算
                Animator animator = ViewAnimationUtils.createCircularReveal(bt2, 0, 0, 0, (float)Math.hypot(bt2.getWidth(), bt2.getHeight()));
                animator.setDuration(1000);
                animator.setInterpolator(new AccelerateInterpolator());
                animator.start();
            }
        });

    }
}

 

 

   Google MaterialDesign 提供转场动画在v7包中:

 //=====================转场动画========================
    // 和PPT播放的时候切换动画差不多
    public void startTranlate(View v){
        Intent intent = new Intent(this, OtherActivityActivity.class);
        startActivity(intent);
        //必须在startActivity或者finish之后,立即执行

        //类视 IOS右拽关闭Actiivty效果
    //    overridePendingTransition( android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        // 第一个通过透明度隐藏,第二个通过透明度显示
	//	overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
        // 这里v7包下的转换场动画
        // 弹出
	//	overridePendingTransition(R.anim.abc_popup_enter, R.anim.abc_popup_exit);
	//	overridePendingTransition(R.anim.abc_grow_fade_in_from_bottom, R.anim.abc_shrink_fade_out_from_bottom);
        // 从下移动
	//	overridePendingTransition(R.anim.abc_slide_in_top, R.anim.abc_slide_out_bottom);
        // 上移动效果
		overridePendingTransition(R.anim.abc_slide_in_bottom, R.anim.abc_slide_out_top);

    }

 源码地址:https://download.csdn.net/download/dreams_deng/12250489

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android属性动画是一种用于在Android应用程序中创建动画效果的框架。它允许您对任意对象的属性进行动画处理,而不仅仅是视图对象。使用属性动画,您可以平滑地改变对象的属性,如位置、大小、颜色等,从而创建流畅的动画效果。 属性动画的基本概念是通过改变对象的属性值来实现动画效果,而不是通过改变视图的位置或绘制来实现。这使得属性动画比传统的补间动画更加灵活和强大。 要使用属性动画,您需要创建一个Animator对象,并指定要动画化的目标对象和属性。然后,您可以定义动画的持续时间、插值器和监听器等属性。最后,启动动画并观察目标对象的属性值的平滑变化。 以下是一个简单的示例,演示如何使用属性动画来平滑地改变视图对象的透明度: ```java // 创建一个属性动画对象,指定要改变的属性为视图对象的透明度 ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha",***.setDuration(1000); // 设置插值器,控制动画的变化速率 animator.setInterpolator(new AccelerateDecelerateInterpolator()); // 启动动画 animator.start(); ``` 在上面的示例中,我们创建了一个ObjectAnimator对象,指定要改变的属性为视图对象的透明度。然后,我们设置了动*** 除了ObjectAnimatorAndroid还提供了一些其他类型的属性动画,如ValueAnimator和AnimatorSet。这些类可用于更复杂的动画效果,如同时播放多个动画或在动画中修改多个属性。 希望这个简介能帮助您理解Android属性动画的基本概念和用法。如果您有更多问题,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值