全站技术
联系方式
全站技术您当前的位置:主页 > 全站技术 >

Android研究之属性动画(Property Animation)完全解析详解下,androidproperty

发布于:2019-01-31 作者:admin

Android研究之属性动画(Property Animation)完全解析详解下,androidproperty


上一篇Android研究之属性动画(Property Animation)完全解析详解上已经基本展示了属性动画的核心用法:

ObjectAnimator实现动画,ValueAnimator实现动画,AnimatorSet的使用等~

当然了属性动画还有一部分的知识点,也能做出很不错的效果,将在本篇博客为您展示~

1、如何使用xml文件来创建属性动画

大家肯定都清楚,View Animator 、Drawable Animator都可以在anim文件夹下创建动画,然后在程序中使用,甚至在Theme中设置为属性值。当然了,属性动画其实也可以在文件中声明:

首先在res下建立animator文件夹,然后建立res/animator/scalex.xml


1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="utf-8"?> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"     android:duration="1000"     android:propertyName="scaleX"     android:valueFrom="1.0"     android:valueTo="2.0"     android:valueType="floatType" > </objectAnimator>

代码:


1 2 3 4 5 6 7 public void scaleX(View view)     {         // 加载动画         Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);         anim.setTarget(mMv);         anim.start();     }

使用AnimatorInflater加载动画的资源文件,然后设置目标,就ok~~是不是很简单,这只是单纯横向的放大一倍~

如果我希望纵向与横向同时缩放呢?则可以怎么定义属性文件:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"     android:ordering="together" >       <objectAnimator         android:duration="1000"         android:propertyName="scaleX"         android:valueFrom="1"         android:valueTo="0.5" >     </objectAnimator>     <objectAnimator         android:duration="1000"         android:propertyName="scaleY"         android:valueFrom="1"         android:valueTo="0.5" >     </objectAnimator>   </set>

使用set标签,有一个orderring属性设置为together,【还有另一个值:sequentially(表示一个接一个执行)】。

上篇博客中忽略了一个效果,就是缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线,所以我决定这个横向,纵向缩小以左上角为中心点:

代码:


1 2 3 4 5 6 7 8 // 加载动画         Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);         mMv.setPivotX(0);         mMv.setPivotY(0);         //显示的调用invalidate         mMv.invalidate();         anim.setTarget(mMv);         anim.start();

很简单,直接给View设置pivotX和pivotY,然后调用一下invalidate,就ok了。

下面看效果图:

好了,通过写xml声明动画,使用set嵌套set,结合orderring属性,也基本可以实现任何动画~~上面也演示了pivot的设置。

2、布局动画(Layout Animations)

主要使用LayoutTransition为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。

基本代码为:


1 2 3 4 5 6 7 8 9 10     LayoutTransition transition = new LayoutTransition();         transition.setAnimator(LayoutTransition.CHANGE_APPEARING,                 transition.getAnimator(LayoutTransition.CHANGE_APPEARING));         transition.setAnimator(LayoutTransition.APPEARING,                 null);         transition.setAnimator(LayoutTransition.DISAPPEARING,                 null);         transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,                 null);         mGridLayout.setLayoutTransition(transition);

 

过渡的类型一共有四种:

LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画

LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画

LayoutTransition.DISAPPEARING  当一个View在ViewGroup中消失时,对此View设置的动画

LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画

LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。

注意动画到底设置在谁身上,此View还是其他View。

好了下面看一个综合的例子:

布局文件:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:id="@+id/id_container"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical" >       <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:onClick="addBtn"         android:text="addBtns" />       <CheckBox         android:id="@+id/id_appear"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:checked="true"         android:text="APPEARING" />       <CheckBox         android:id="@+id/id_change_appear"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:checked="true"         android:text="CHANGE_APPEARING" />       <CheckBox         android:id="@+id/id_disappear"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:checked="true"         android:text="DISAPPEARING" />       <CheckBox           android:id="@+id/id_change_disappear"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:checked="true"         android:text="CHANGE_DISAPPEARING " />   </LinearLayout>

代码:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 package com.example.zhy_property_animation;   import android.animation.LayoutTransition; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.GridLayout;   public class LayoutAnimaActivity extends Activity implements         OnCheckedChangeListener {     private ViewGroup viewGroup;     private GridLayout mGridLayout;     private int mVal;     private LayoutTransition mTransition;       private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear;       @Override     public void onCreate(Bundle savedInstanceState)     {         super.onCreate(savedInstanceState);         setContentView(R.layout.layout_animator);         viewGroup = (ViewGroup) findViewById(R.id.id_container);           mAppear = (CheckBox) findViewById(R.id.id_appear);         mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear);         mDisAppear = (CheckBox) findViewById(R.id.id_disappear);         mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear);           mAppear.setOnCheckedChangeListener(this);         mChangeAppear.setOnCheckedChangeListener(this);         mDisAppear.setOnCheckedChangeListener(this);         mChangeDisAppear.setOnCheckedChangeListener(this);           // 创建一个GridLayout         mGridLayout = new GridLayout(this);         // 设置每列5个按钮         mGridLayout.setColumnCount(5);         // 添加到布局中         viewGroup.addView(mGridLayout);         //默认动画全部开启         mTransition = new LayoutTransition();         mGridLayout.setLayoutTransition(mTransition);       }       /**      * 添加按钮      *      * @param view      */     public void addBtn(View view)     {         final Button button = new Button(this);         button.setText((++mVal) + "");         mGridLayout.addView(button, Math.min(1, mGridLayout.getChildCount()));         button.setOnClickListener(new OnClickListener()         {               @Override             public void onClick(View v)             {                 mGridLayout.removeView(button);             }         });     }       @Override     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)     {         mTransition = new LayoutTransition();         mTransition.setAnimator(                 LayoutTransition.APPEARING,                 (mAppear.isChecked() ? mTransition                         .getAnimator(LayoutTransition.APPEARING) : null));         mTransition                 .setAnimator(                         LayoutTransition.CHANGE_APPEARING,                         (mChangeAppear.isChecked() ? mTransition                                 .getAnimator(LayoutTransition.CHANGE_APPEARING)                                 : null));         mTransition.setAnimator(                 LayoutTransition.DISAPPEARING,                 (mDisAppear.isChecked() ? mTransition                         .getAnimator(LayoutTransition.DISAPPEARING) : null));         mTransition.setAnimator(                 LayoutTransition.CHANGE_DISAPPEARING,                 (mChangeDisAppear.isChecked() ? mTransition                         .getAnimator(LayoutTransition.CHANGE_DISAPPEARING)                         : null));         mGridLayout.setLayoutTransition(mTransition);     } }

效果图:

动画有点长,耐心点看,一定要注意,是对当前View还是其他Views设置的动画。

当然了动画支持自定义,还支持设置时间,比如我们修改下,添加的动画为:


1 2 3 mTransition.setAnimator(LayoutTransition.APPEARING, (mAppear                 .isChecked() ? ObjectAnimator.ofFloat(this, "scaleX", 0, 1)                 : null));

则效果为:

原本的淡入,变成了宽度从中间放大的效果~~是不是还不错~~

3、View的anim方法

在SDK11的时候,给View添加了animate方法,更加方便的实现动画效果。

布局文件:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <RelativeLayout 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"     >       <ImageView         android:id="@+id/id_ball"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:src="@drawable/bol_blue" />       <LinearLayout         android:layout_width="fill_parent"         android:layout_height="wrap_content"         android:layout_alignParentBottom="true"         android:orientation="horizontal" >           <Button             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:onClick="viewAnim"             android:text="View Anim" />           <Button             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:onClick="propertyValuesHolder"             android:text="PropertyValuesHolder " />                </LinearLayout>   </RelativeLayout>

代码:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 package com.example.zhy_property_animation;   import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.app.Activity; import android.os.Bundle; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.widget.ImageView;   public class ViewAnimateActivity extends Activity {     protected static final String TAG = "ViewAnimateActivity";       private ImageView mBlueBall;     private float mScreenHeight;       @Override     protected void onCreate(Bundle savedInstanceState)     {         super.onCreate(savedInstanceState);         setContentView(R.layout.view_animator);           DisplayMetrics outMetrics = new DisplayMetrics();         getWindowManager().getDefaultDisplay().getMetrics(outMetrics);         mScreenHeight = outMetrics.heightPixels;         mBlueBall = (ImageView) findViewById(R.id.id_ball);       }       public void viewAnim(View view)     {         // need API12         mBlueBall.animate()//                 .alpha(0)//                 .y(mScreenHeight / 2).setDuration(1000)                 // need API 12                 .withStartAction(new Runnable()                 {                     @Override                     public void run()                     {                         Log.e(TAG, "START");                     }                     // need API 16                 }).withEndAction(new Runnable()                 {                       @Override                     public void run()                     {                         Log.e(TAG, "END");                         runOnUiThread(new Runnable()                         {                             @Override                             public void run()                             {                                 mBlueBall.setY(0);                                 mBlueBall.setAlpha(1.0f);                             }                         });                     }                 }).start();     }                                                                                                                                                  }

简单的使用mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000).start()就能实现动画~~不过需要SDK11,此后在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前,和动画后执行一些操作。当然也可以.setListener(listener)等操作。

使用ObjectAnimator实现上面的变化,我们可以使用:PropertyValueHolder


1 2 3 4 5     PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,                 0f, 1f);         PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0,                 mScreenHeight / 2, 0);         ObjectAnimator.ofPropertyValuesHolder(mBlueBall, pvhX, pvhY).setDuration(1000).start();

效果与上面一样。

运行结果:

好了,关于属性动画基本所有的用法到此结束~~~~欢迎大家一起学习,一起进步。

源码下载:zhy_property_animation


我想要在android程序中,出现一副动画,怎做?

在Android的FrameWork中,提供三种动画的实现方式:逐帧(Frame)动画、视图动画(View Animation)和属性动画(Property Animation)。

根据SDK中的描述,这三者的功能强大程度为:逐帧动画<视图动画<属性动画。
一、逐帧动画:
该动画的方式就是将动画的过程的每一张静态图片都收集起来,然后依次显示这些图片,利用人眼的“视觉停留”的原理,给用户产生动画的效果。

二、视图动画:
也称为补间(Tween)动画,根据这两个定义可以看出该动画方式的一些特征:
1)该动画方式只是针对于View对象,例如ImageView、Button等;
2)实现该动画时,只需要给出两个关键帧的相关属性,Android会给你生给定成时间段内的两关键帧的动画渐变过程。

三、属性动画:
Android在3.0中引入了属性动画。和视图动画专注与视图效果不同,它更专注于对象的属性的变化,通过改变对象的属性而实现动画,不论该对象是否可见。例如:你使用视图动画将一个Button放大一倍,在界面上的效果可以实现,但是该Button的触摸响应区域还是和原来的一样,也就是说,视图动画并不是真正的将该Button放大一倍。
www.linuxidc.com/Linux/2013-01/78069.htm
 
Qt对同一对象按顺序执行一组动画效果(QPropertyAnimation)的demo示例

QPropertyAnimation *anim=new QPropertyAnimation(this,"pos");
anim->setDuration(2000); //动画时间

anim->setKeyValueAt(0,QPoint(0,0)); //动画开始

anim->setKeyValueAt(0.15,QPoint(0,500)); //第一个动画完毕并且开始第二个动画

anim->setEndValue(QPoint(0,0)); //第二个动画完毕

anim->setEasingCurve(QEasingCurve::OutBounce);
anim->start(); //执行动画
 

http://www.bkjia.com/Androidjc/860835.htmlwww.bkjia.comtruehttp://www.bkjia.com/Androidjc/860835.htmlTechArticleAndroid研究之属性动画(Property Animation)完全解析详解下,androidproperty 上一篇Android研究之属性动画(Property Animation)完全解析详解上已经基...

本文源自: 环亚国际