
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的进阶实例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)