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

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", 0, 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", 0,
      mScreenHeight / 2, 0);
  ObjectAnimator.ofPropertyValuesHolder(mBlueBall, pvhX, pvhY).setDuration(1000).start();

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

(0)

相关推荐

  • 图文详解Android属性动画

    Android中的动画分为视图动画(View Animation).属性动画(Property Animation)以及Drawable动画.从Android 3.0(API Level 11)开始,Android开始支持属性动画,本文主要讲解如何使用属性动画.关于视图动画可以参见博文<Android四大视图动画图文详解>. 一.概述 视图动画局限比较大,如下所述: 1.视图动画只能使用在View上面. 2.视图动画并没有真正改变View相应的属性值,这导致了UI效果与实际View状态存在差异

  • Android源码解析之属性动画详解

    前言 大家在日常开发中离不开动画,属性动画更为强大,我们不仅要知道如何使用,更要知道他的原理.这样,才能得心应手.那么,今天,就从最简单的来说,了解下属性动画的原理. ObjectAnimator .ofInt(mView,"width",100,500) .setDuration(1000) .start(); ObjectAnimator#ofInt 以这个为例,代码如下. public static ObjectAnimator ofInt(Object target, Stri

  • Android动画 实现开关按钮动画(属性动画之平移动画)实例代码

    Android动画 实现开关按钮动画(属性动画之平移动画),最近做项目,根据项目需求,有一个这样的功能,实现类似开关的动画效果,经过自己琢磨及上网查找资料,终于解决了,这里就记录下: 在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率.另外说到动画,在Android里面支持3种动画: 逐帧动画(Frame Animation).补间动画(Tween Animation)和属性动画(Property Animation),至于这

  • Android 动画(View动画,帧动画,属性动画)详细介绍

    0. 前言  Android动画是面试的时候经常被问到的话题.我们都知道Android动画分为三类:View动画.帧动画和属性动画. 先对这三种动画做一个概述: View动画是一种渐进式动画,通过图像的平移.缩放.旋转和透明度等各种渐进式变换完成动画效果. 帧动画是通过不停的切换图片实现动画效果. 属性动画是不停的改变对象的属性来实现动画效果.本文原创,转载请注明出处: http://blog.csdn.net/seu_calvin/article/details/52724655 1.  Vi

  • Android属性动画实现布局的下拉展开效果

    在Android的3.0之后,google又提出了属性动画的这样一个框架,他可以更好的帮助我们实现更丰富的动画效果.所以为了跟上技术的步伐,今天就聊一聊属性动画. 这一次的需求是这样的:当点击一个View的时候,显示下面隐藏的一个View,要实现这个功能,需要将V iew的visibility属性设置gone为visible即可,但是这个过程是一瞬间的,并不能实现我们要的效果.所以,属性动画是个不错的方案. 先把效果贴上 第一个:  第二个: 前面的这个是隐藏着,后面这个是显示的.当点击这个箭头

  • Android 属性动画原理与DataBinding

    Android 属性动画原理与DataBinding 看到这个标题的时候你可能会有疑问,属性动画和 DataBinding 之间有什么关系?我个人理解的是:它们内部的实现思想有相似之处.这篇文章主要对 Android 属性动画的知识通过文字进行整理记录,内容参考于<Android开发艺术探索>,在最后会给出我如此理解属性动画和 DataBinding 的原因. Android动画概述: Android 的动画可以分为三种:View 动画.帧动画和属性动画,View 动画通过对场景里的对象不断做

  • Android 自定义view和属性动画实现充电进度条效果

    近期项目中需要使用到一种类似手机电池充电进度的动画效果,以前没学属性动画的时候,是用图片+定时器的方式来完成的,最近一直在学习动画这一块,再加上复习一下自定义view的相关知识点,所以打算用属性动画和自定义view的方式来完成这个功能,将它开源出来,供有需要的人了解一下相关的内容. 本次实现的功能类似下面的效果: 接下来便详细解析一下如何完成这个功能,了解其中的原理,这样就能举一反三,实现其他类似的动画效果了. 详细代码请看大屏幕 https://github.com/crazyandcoder

  • Android属性动画实现炫酷的登录界面

    我们聊聊我们常写的登录界面,这个界面我相信很多人都写过,而且也没什么难度,但是如果要实现比较不一般的效果,那就要花点心思了,先看看项目的效果吧: 我一直都不知道怎么在编辑框连设置图片大小,所以这个图不怎么样适配编辑框了,大家先凑合着看看. 我先讲讲思路,当我们输入完账号跟密码之后,点击登录,那这个输入框就慢慢的消失,在消失后,紧接着就出现这个进度的界面. 思路有了,那我们就开始编码了: 新建一个项目,然后系统生成了一个MainActivity.java文件和activity_main.xml文件

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

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

  • Android中显示GIF动画的实现代码

    本文实例讲述了Android中显示GIF动画的实现代码.分享给大家供大家参考,具体如下: gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个.经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示代码,我下载过几个,但是都不是很理想,不是我完全想要的.所以有时候就得自己学会总结,把开源的东西整理成自己的,现在无聊,也正好有朋友需要,所以现在整理了一下,留着以后备用! 废话不多说,直接上图: 在这里主要用

  • Android中persistent属性用法详解

    本文实例讲述了Android中persistent属性用法.分享给大家供大家参考,具体如下: 前段时间在研究telephony时,一直没有在framework下发现对telephony的初始化(PhoneFactory.Java中的makeDefaultPhones函数)的调用.结果全局搜索之后发现在application PhoneApp(packages/apps/Phone)中调用了.但是application PhoneApp既没有被Broadcast唤醒,也没有被其他service调用

  • Android中layout属性大全

    本文总结了Android中layout属性的含义与用法.分享给大家供大家参考.具体如下: 布局: AbsoluteLayout(绝对布局): xmlns:android="http://scmemas.android.com/apk/res/android" style="@..." android:clipChildren="true|false" android:clipToPadding="true|false" and

  • Android中Activity过渡动画的实例讲解

    目录 前言 分解动画 效果视频 解析 滑动动画 效果视频 解析 淡出动画 效果视频 解析 共享元素 共享单个元素 解析 共享多个元素 效果视频 全部代码 总结 前言 以前Activty之间得跳转非常生硬,自Android.5X后,Google对Activity的切换设计更多丰富的动画效果. Android 5.X提供了三种Transition类型,具体如下: ✧进入:一个进人的过渡动画决定Activity中的所有的视图怎么进入屏幕. ✧退出:一个退出的过渡动画决定-个Activity 中的所有视

  • Android中播放Gif动画取巧的办法

    由于做的项目,要有个动画的等待效果,第一时间想到的就是Gif(懒,省事),但是试了好多据说能播放Gif的控件,也写过,但是放到魅族手机上就是不能播放,所有就想了个招,既然Gif能在浏览器上播放,那android 的 WebView 也能播放,写了个Demo,果然能播放. 1.将gif的文件放到android的资源文件夹里面 2.写个html,将android的gif源放到WebView里面去加载 <RelativeLayout xmlns:android="http://schemas.a

  • Android中利用viewflipper动画切换屏幕效果

    整个项目的 package com.example.viewflipper; import android.R.integer; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector.OnDoubleTapListener; import android.view.Menu; import android.view.Me

  • Android 中ScrollView嵌套GridView,ListView的实例

    Android 中ScrollView嵌套GridView,ListView的实例 在Android开发中,经常有一些UI需要进行固定style的动态布局,然而由于现在的UI都喜欢把一个界面拉的很长,所以我们很多情况下需要使用ScrollView来嵌套列表控件来实现UI.这样就导致了很多不顺心的问题. 问题一:列表控件显示不完全 原因是嵌套情况下,ScrollView不能正确的计算列表控件的高度. 有两种解决方案 方案一 在适配器赋值完成后代码动态计算列表的高度.这里贴出ListView的计算代

  • Android 中TeaPickerView数据级联选择器功能的实例代码

    Github地址 YangsBryant/TeaPickerView (Github排版比较好,建议进入这里查看详情,如果觉得好,点个star吧!) 引入module allprojects { repositories { google() jcenter() maven { url 'https://www.jitpack.io' } } } implementation 'com.github.YangsBryant:TeaPickerView:1.0.2' 主要代码 public cla

  • Android中View跟随手指滑动效果的实例代码

    本文讲述了Android中View跟随手指滑动效果的实例代码.分享给大家供大家参考,具体如下: 1.android View 主要6种滑动方法,分别是 layout() offsetLeftAndRight()和offsetTopAndBottom() LayoutParams scrollBy()和 scrollTo() Scroller 动画 2.实现效果图 3.自定义中使用layout()方法实习view的滑动 public class MoveView extends View { pr

随机推荐