Android中编写属性动画PropertyAnimation的进阶实例

Android中编写属性动画PropertyAnimation的进阶实例,第1张

概述0、基础回顾PropertyAnimation,属性动画,顾名思义就是利用对象的属性变化形成动画的效果。属性动画的类可以用Animator这个抽象类来表示,通常使用它的子类:AnimatorSet和ValueAnimator,同时ValueAnimator有两个子

0、基础回顾
PropertyAnimation,属性动画,顾名思义就是利用对象的属性变化形成动画的效果。属性动画的类可以用Animator这个抽象类来表示,通常使用它的子类:AnimatorSet和ValueAnimator,同时ValueAnimator有两个子类分别是ObjectAniamtor和TimeAnimator。
定义属性动画的XML资源的时候通常可以是如下三个元素之一作为根元素:
<set>元素:该资源元素代表的是AniamtorSet类,这个类可以包含<set>,<objectAniamtor>,<animator>三个子元素。
<objectAnimator>元素:用于定义objectAniamtor类。
<animator>元素:用于定义ValueAnimator类。
比如说这里一个资源文件的定义如下:

<set androID:ordering="[together|sequentially]">   <objectAnimator       androID:propertyname="string"      androID:duration="int"      androID:valueFrom="float|int|color"      androID:valueto="float|int|color"      androID:startOffset="int"      androID:repeatCount="int"      androID:interpolator=""      androID:repeatMode="[reapeat|reverse]"      androID:valueType="[intType|floatType]"/>    <animator             androID:duration="int"      androID:valueFrom="float|int|color"      androID:valueto="float|int|color"      androID:startOffset="int"      androID:repeatCount="int"      androID:interpolator=""      androID:repeatMode="[reapeat|reverse]"      androID:valueType="[intType|floatType]"/>   <set>    ....  </set> </set>

属性文件通常保存在animator文件夹下面。

1、如何使用xml文件来创建属性动画
大家肯定都清楚,VIEw Animator 、Drawable Animator都可以在anim文件夹下创建动画,然后在程序中使用,甚至在theme中设置为属性值。当然了,属性动画其实也可以在文件中声明:
首先在res下建立animator文件夹,然后建立res/animator/scalex.xml

<?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> 

代码:

public voID scaleX(VIEw vIEw)   {     // 加载动画     Animator anim = AnimatorInflater.loadAnimator(this,R.animator.scalex);     anim.setTarget(mMv);     anim.start();   } 

使用AnimatorInflater加载动画的资源文件,然后设置目标,就ok~~是不是很简单,这只是单纯横向的放大一倍~
如果我希望纵向与横向同时缩放呢?则可以怎么定义属性文件:

<?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(表示一个接一个执行)】。
上篇博客中忽略了一个效果,就是缩放、反转等都有中心点或者轴,默认中心缩放,和中间对称线为反转线,所以我决定这个横向,纵向缩小以左上角为中心点:
代码:

// 加载动画     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为布局的容器设置动画,当容器中的视图层次发生变化时存在过渡的动画效果。
基本代码为:

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); 

过渡的类型一共有四种:
(1)LayoutTransition.APPEARING 当一个VIEw在VIEwGroup中出现时,对此VIEw设置的动画
(2)LayoutTransition.CHANGE_APPEARING 当一个VIEw在VIEwGroup中出现时,对此VIEw对其他VIEw位置造成影响,对其他VIEw设置的动画
(3)LayoutTransition.disAPPEARING  当一个VIEw在VIEwGroup中消失时,对此VIEw设置的动画
(4)LayoutTransition.CHANGE_disAPPEARING 当一个VIEw在VIEwGroup中消失时,对此VIEw对其他VIEw位置造成影响,对其他VIEw设置的动画
(5)LayoutTransition.CHANGE 不是由于VIEw出现或消失造成对其他VIEw位置造成影响,然后对其他VIEw设置的动画。
注意动画到底设置在谁身上,此VIEw还是其他VIEw。
好了下面看一个综合的例子:
布局文件:

<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> 

代码:

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设置的动画。
当然了动画支持自定义,还支持设置时间,比如我们修改下,添加的动画为:

mTransition.setAnimator(LayoutTransition.APPEARING,(mAppear         .isChecked() ? ObjectAnimator.offloat(this,"scaleX",1)         : null)); 

则效果为:

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

3、VIEw的anim方法
在SDK11的时候,给VIEw添加了animate方法,更加方便的实现动画效果。
布局文件:

<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> 

代码:

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

PropertyValuesHolder pvhX = PropertyValuesHolder.offloat("Alpha",1f,0f,1f);   PropertyValuesHolder pvhY = PropertyValuesHolder.offloat("y",mScreenHeight / 2,0);   ObjectAnimator.ofPropertyValuesHolder(mBlueBall,pvhX,pvhY).setDuration(1000).start(); 

效果与上面一样。
运行结果:

总结

以上是内存溢出为你收集整理的Android中编写属性动画PropertyAnimation的进阶实例全部内容,希望文章能够帮你解决Android中编写属性动画PropertyAnimation的进阶实例所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1149417.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存