属性动画 LayoutTransition AnimatorInflater Keyframe 新特性
LayoutTransition设置动画
使用LayoutTransition可为布局的容器设置动画,当容器中的视图层次发生变化时产生相应的过渡的动画效果过渡的类型一共有四种:
- 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设置的动画
AnimateLayoutChanges动画:ViewGroup的xml属性中有一个animateLayoutChanges属性,设置该属性为true,可以添加ViewGroup增加view的过渡效果:示例:mTransition = new LayoutTransition();mTransition.setAnimator(LayoutTransition.APPEARING, ObjectAnimator.ofFloat(this, "scaleX", 0, 1));mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, mTransition.getAnimator(LayoutTransition.CHANGE_APPEARING));mTransition.setAnimator(LayoutTransition.DISAPPEARING, mTransition.getAnimator(LayoutTransition.DISAPPEARING));mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, mTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING));gl_container.setLayoutTransition(mTransition);
XML中设置属性动画
set标签的orderring属性设置为together表示同时播放,sequentially表示一个接一个播放缩放、反转等都有中心点或者轴,默认为中心缩放,中间对称线为反转线,通过setPivotX(),setPivotY()可改变中心的位置Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);mChangeAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴mChangeAppear.setPivotY(0);mChangeAppear.invalidate();//设置后要显示的调用invalidateanim.setTarget(mChangeAppear);anim.start();
KeyFrame动画
KeyFrame是一个【时间/值】对,通过它可以定义一个在特定时间的特定状态,即【关键帧】,而且在两个keyFrame之间可以定义不同的【Interpolator】,就好像多个动画的拼接,第一个动画的结束点是第二个动画的开始点。 KeyFrame是抽象类,要通过ofInt(),ofFloat(),ofObject()获得适当的KeyFrame,然后通过PropertyValuesHolder.ofKeyframe获得PropertyValuesHolder对象,然后通过ObjectAnimator.ofPropertyValuesHolder获得一个Animator对象。Keyframe kf0 = Keyframe.ofInt(0, 300);Keyframe kf1 = Keyframe.ofInt(0.2f, 800);//动画开始1/5时 Width=600Keyframe kf2 = Keyframe.ofInt(0.4f, 300);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(mDisAppear, pvhRotation);rotationAnim.setDuration(5000).start();
View的animate动画-新API
在SDK11的时候,给View添加了animate方法,可以使用一行代码非常方便的实现动画效果。 此后在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前、动画后执行一些操作,当然也可以.setListener(listener)完成此操作。 如:view.animate().alpha(0.2F).y(1000).setDuration(2000).withStartAction(new Runnable() {@Overridepublic void run() {mChangeDisAppear.setX(200);}}).withEndAction(new Runnable() {@Overridepublic void run() {mChangeDisAppear.setRotation(-30);//是相对初始值转了-30°}}).start();
我们也可以使用PropertyValueHolder实现上面的变化,效果与上面一样PropertyValuesHolder pvhA = PropertyValuesHolder.ofFloat("alpha", 1f, 0f);PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 0, 200);ObjectAnimator.ofPropertyValuesHolder(iv, pvhA, pvhY).setDuration(1000).start();注意,这种动画不再是View动画了,而是属性动画的一种,因为改变了控件的实际属性。
代码
public class MainActivity extends Activity implements OnCheckedChangeListener {private GridLayout gl_container;//放置按钮的父布局private int mVal;//按钮的编号private LayoutTransition mTransition;//布局动画,当容器中的视图发生变化时存在过渡的动画效果private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);gl_container = (GridLayout) findViewById(R.id.gl_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);//CheckBox选中状态改变监听,默认全部选中,即动画全部开启mAppear.setOnCheckedChangeListener(this);mChangeAppear.setOnCheckedChangeListener(this);mDisAppear.setOnCheckedChangeListener(this);mChangeDisAppear.setOnCheckedChangeListener(this);mTransition = new LayoutTransition();gl_container.setLayoutTransition(mTransition);}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {mTransition = new LayoutTransition();//当一个View在ViewGroup中【出现】时,对此【View】设置的动画mTransition.setAnimator(LayoutTransition.APPEARING, //=2,下面使用的是自定义的动画(mAppear.isChecked() ? ObjectAnimator.ofFloat(this, "scaleX", 0, 1) : null));//当一个View在ViewGroup中【出现】时,对此View对其他View位置造成影响,对【其他View】设置的动画mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING,//=0,下面都是使用默认的动画(mChangeAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.CHANGE_APPEARING) : null));//当一个View在ViewGroup中【消失】时,对此【View】设置的动画mTransition.setAnimator(LayoutTransition.DISAPPEARING, //=3(mDisAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.DISAPPEARING) : null));//当一个View在ViewGroup中【消失】时,对此View对其他View位置造成影响,对【其他View】设置的动画mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,//=1(mChangeDisAppear.isChecked() ? mTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING) : null));gl_container.setLayoutTransition(mTransition);}// 向GridLayout中添加按钮public void addBtn(View view) {final Button button = new Button(this);button.setText("" + (++mVal));gl_container.addView(button, gl_container.getChildCount());//放置在最后那个位置button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {gl_container.removeView(button);}});}//XML属性动画1,单个动画public void xmlAnim1(View view) {// 加载动画Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);mAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴mAppear.invalidate();//设置后要显示的调用invalidate才能生效anim.setTarget(mAppear);anim.start();}//XML属性动画2,多动画public void xmlAnim2(View view) {Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);mChangeAppear.setPivotX(0);//设置缩放、反转时的中心点或者轴mChangeAppear.setPivotY(0);mChangeAppear.invalidate();//设置后要显示的调用invalidateanim.setTarget(mChangeAppear);anim.start();}//Keyframe动画public void keyframe(View view) {Keyframe kf0 = Keyframe.ofInt(0, 300);Keyframe kf1 = Keyframe.ofInt(0.2f, 800);//动画开始1/5时 Width=600Keyframe kf2 = Keyframe.ofInt(0.4f, 300);Keyframe kf3 = Keyframe.ofInt(0.6f, 100);Keyframe kf4 = Keyframe.ofInt(0.8f, 50);Keyframe kf5 = Keyframe.ofInt(1f, 500);PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf3, kf4, kf5);ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(mDisAppear, pvhRotation);rotationAnim.setDuration(5000).start();}//新版本View动画public void viewAnimForNew(View view) {mChangeDisAppear.animate().alpha(0.2F).y(1000).setDuration(2000).withStartAction(new Runnable() {@Overridepublic void run() {mChangeDisAppear.setX(200);mChangeDisAppear.setRotation(180);}}).withEndAction(new Runnable() {@Overridepublic void run() {mChangeDisAppear.setX(200);mChangeDisAppear.setY(300);mChangeDisAppear.setAlpha(1.0f);mChangeDisAppear.setRotation(-30);//是相对初始值转了-30°}}).start();}}
XML动画
scalex.xml<?xml version="1.0" encoding="utf-8"?><objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="500"android:interpolator="@android:anim/accelerate_interpolator"android:propertyName="scaleX"android:repeatCount="1"android:repeatMode="reverse"android:startOffset="1000"android:valueFrom="2.5"android:valueTo="10"android:valueType="floatType" ></objectAnimator>
scale.xml <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="sequentially" ><objectAnimatorandroid:duration="500"android:propertyName="rotationX"android:startOffset="0"android:valueFrom="0"android:valueTo="360" ></objectAnimator><objectAnimatorandroid:duration="200"android:propertyName="scaleY"android:startOffset="500"android:valueFrom="1"android:valueTo="1.7" ></objectAnimator><objectAnimatorandroid:duration="200"android:propertyName="scaleX"android:startOffset="700"android:valueFrom="1"android:valueTo="1.5" ><objectAnimatorandroid:duration="100"android:propertyName="alpha"android:startOffset="900"android:valueFrom="1"android:valueTo="0.2" ></objectAnimator></objectAnimator></set>
布局
![]()
<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" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="xmlAnim1"android:text="XML属性动画1" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="xmlAnim2"android:text="XML属性动画2" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="keyframe"android:text="Keyframe动画" /><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:onClick="viewAnimForNew"android:text="view的animate动画" /></LinearLayout><CheckBoxandroid:id="@+id/id_appear"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#200f"android:checked="true"android:text="APPEARING" /><CheckBoxandroid:id="@+id/id_change_appear"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#2ff0"android:checked="true"android:text="CHANGE_APPEARING" /><CheckBoxandroid:id="@+id/id_disappear"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#20f0"android:checked="true"android:text="DISAPPEARING" /><CheckBoxandroid:id="@+id/id_change_disappear"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#2f00"android:checked="true"android:text="CHANGE_DISAPPEARING " /><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dp"android:onClick="addBtn"android:text="点击添加按钮,点击添加的按钮删除按钮" /><GridLayoutandroid:id="@+id/gl_container"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:animateLayoutChanges="false"android:background="#40f0"android:columnCount="5" /></LinearLayout>
附件列表
属性动画 LayoutTransition AnimatorInflater Keyframe 新特性的更多相关文章
- 每日一问:到底为什么属性动画后 View 在新位置还能响应事件
在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...
- CSS3新特性(阴影、动画、渐变、变形、伪元素等)
CSS3与页面布局学习总结(六)--CSS3新特性(阴影.动画.渐变.变形.伪元素等) 目录 一.阴影 1.1.文字阴影 1.2.盒子阴影 二.背景 2.1.背景图像尺寸 2.2.背景图像显示的原 ...
- Android5.0新特性之——按钮点击效果动画(涟漪效果)
Android5.0 Material Design设计的动画效果 RippleDrawable涟漪效果 涟漪效果是Android5.0以后的新特性.为了兼容性,建议新建drawable-v21文件夹 ...
- JS 4 新特性:混合属性(mixins)
Ext JS4的新特征1:混合属性(mixins) 组合是Extjs4的新特性,可用于实现多继承的情况.该属性会以同步方式加载类文件,并实例化该类(译者推理其内部使用Ext.create方法).直接上 ...
- Android5.0新特性——全新的动画(animation)
全新的动画 在Material Design设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性.Material主题为控件和Activity的过渡提供了一些默认的动画,在android ...
- 最新iOS 6 in Xcode4.5新特性——Storyboard和属性自动绑定
最新iOS 6 in Xcode4.5新特性编程之二(上)——Storyboard和属性自动绑定 从Xcode 4.3开始,Storyboard 就是iOS 5和iOS 6中令人兴奋的一个新特性,他将 ...
- HTML5基础知识汇总_(2)自己定义属性及表单新特性
自己定义属性data-* 说起这个属性,事实上如今非经常见了;怎么说呢,由于在一些框架都能看到他的身影!!! 比方Jquery mobile,里面非常频繁的使用了这个属性; 这个属性是哪里来的-.当然 ...
- html5新特性contenteditable 属性更容易实现动态表单
介绍html5新特性的一个属性:contenteditable 作用域全局.所有的块标签都可以,例如:span.p.div.td等标签.但是,不可以作用域<br/>类型的标签. conte ...
- css3的新特性选择器-------属性选择器
自己学css的时候比较乱,这次趁着复习把css3的新特性选择器和css2以前不怎么用的选择器做一个总结 <div id="parent"> <p>I'm a ...
随机推荐
- c#利用WebClient和WebRequest获取网页源代码
C#中一般是可以利用WebClient类和WebRequest类获取网页源代码.下面分别说明这两种方法的实现. WebClient类获取网页源代码 WebClient类 WebClient ...
- 解决Mac上Android开发时adb连接不到手机问题
今天在Mac OS上进行Android开发的时候,打开eclipse连接不到手机MX4问题 1. 插入手机打开 Terminal,输入 system_profiler SPUSBDataType 2 ...
- Android学习----ADB
adb是什么?:adb的全称为Android Debug Bridge,就是起到调试桥的作用.通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序,说白了就是debug工具.a ...
- $_CFG = load_config(); /* 载入系统参数 */
ecshop 中$_CFG数组主要是放置一些系统参数,并且全站共享的数据,在使用的时候,ecshop里面常常以$GLOBALS['_CFG']全局变量的模式来处理. ecshop 的$GLOBALS[ ...
- Hazelcase 简介
原博客地址:http://blog.csdn.net/zhu_tianwei/article/details/47984599 Hazelcast是一种内存数据网格in-memory data gri ...
- What qualities characterize a great PhD student
省理工计算机教授David Karger接触了许多世界上最杰出的博士生,近日总结出了优秀博士通常具备的五点品质:0 过人的智力 1 好奇心 2 创造力 3 纪律性与生产力 4 与观众沟通 5 与伙伴沟 ...
- mongose排序查询
Kc.find({bjid:req.params.bjid}).sort({'_id':1}).exec(function(err,kcs){ if(err){ res.json({no:0,msg: ...
- VS2012 利用正则统计项目代码行数
原文:VS2012 利用正则统计项目代码行数 #开头和/开头或者空行都不计入代码量, 搜索出来以后最后一行就是代码行数了:
- Windows 7 mklink命令详解
mklink是Windows 7下的一个类似于linux下In的命令,其作用是在NTFS文件系统中创建文件或目录的链接(类似于桌面快捷方式).如果加以利用其发挥的作用是非常的大的,不仅可以帮助我们节省 ...
- 7.3.2 Using Backups for Recovery 使用备份用于恢复
7.3.2 Using Backups for Recovery 使用备份用于恢复 现在,假设我们有一个灾难性的crash 在星期三上午8点. 需要恢复从备份恢复,为了恢复,我们首选需要恢复最近的全备 ...