Android自定义view教程03---Android 属性动画 详解

 1 package com.example.donghuatest;
 2
 3 import android.animation.ObjectAnimator;
 4 import android.animation.PropertyValuesHolder;
 5 import android.animation.ValueAnimator;
 6 import android.animation.ValueAnimator.AnimatorUpdateListener;
 7 import android.app.Activity;
 8 import android.os.Bundle;
 9 import android.view.View;
10 import android.widget.ImageView;
11
12 public class MainActivity extends Activity {
13
14     // 比较简单的属性动画
15     private ObjectAnimator alphaAnimation = new ObjectAnimator();
16
17     private ImageView imageView;
18
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_main);
23
24         imageView = (ImageView) this.findViewById(R.id.iv);
25         imageView.setOnClickListener(new View.OnClickListener() {
26
27             @Override
28             public void onClick(final View v) {
29                 rotateyAnimRunFirst(v);
30                 // rotateyAnimRunSecond(v);
31                 // rotateyAnimRunThird(v);
32             }
33         });
34
35     }
36
37     /**
38      * 横向翻转 Y轴不变
39      *
40      * @param view
41      */
42     public void rotateyAnimRunFirst(final View view) {
43         ObjectAnimator anim = ObjectAnimator.ofFloat(view, "rotationY", 0.0F,
44                 360.0F).setDuration(500);
45         anim.start();
46     }
47
48     /**
49      * 让这个图片由大变小 并且透明度也有变化 注意这个透明度变化到0的时候就结束了 并没有回复到初始状态
50      *
51      * @param view
52      */
53     public void rotateyAnimRunSecond(final View view) {
54         ObjectAnimator anim = ObjectAnimator.ofFloat(view, "zhy", 1.0F, 0.0F)
55                 .setDuration(500);
56         anim.start();
57         anim.addUpdateListener(new AnimatorUpdateListener() {
58             @Override
59             public void onAnimationUpdate(ValueAnimator animation) {
60                 float cVal = (Float) animation.getAnimatedValue();
61                 view.setAlpha(cVal);
62                 view.setScaleX(cVal);
63                 view.setScaleY(cVal);
64             }
65         });
66
67     }
68
69     /**
70      * 另外一种一个动画 包含多种效果的方法 也更加方便 和第二个相比 他最终的结果仍是初始化的结果
71      *
72      * @param view
73      */
74     public void rotateyAnimRunThird(final View view) {
75         PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,
76                 0f, 1f);
77         PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f,
78                 0, 1f);
79         PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f,
80                 0, 1f);
81         ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY, pvhZ)
82                 .setDuration(1000).start();
83
84     }
85
86 }

这是写的一个属性动画的小demo,大家可以跑起来运行一下,总共有3个效果。

rotateyAnimRunFirst 这个函数 其实主要就是一个翻转的效果。
rotateyAnimRunSecond 这个函数 就是把图片从大到小变化一次 ,并且透明度也有变化。 相当于是一个混合的动画效果
rotateyAnimRunThird 这个函数和上面第二个函数效果其实差不多,只不过 这个到最后会回复到一开始的效果,并且用的方法也不一样。

其实这个属性动画,也是很好理解的,相对于其他两种动画来说,属性动画更改的是view 本身。
rotateyAnimRunFirst 这个函数 里面可以看到 传进去了
rotationY 这个值,到这里很多人就要问,这个地方的值要传什么,其实这个地方很好理解。对于第一种函数的 调用方式来说

你传什么值,这个属性动画就更改什么值,当然前提是这个值的 get set方法 必须有。

你如果传的值 没有get set方法的话 那这个属性动画 肯定是不起作用的。

比如我们这里的代码是更改的imageview 我们可以看一下 imageview 继承自 view

而view里面 是有这些get set方法的
 1  float mRotationY = 0f;
 2
 3         /**
 4          * The degrees rotation around the horizontal axis through the pivot point.
 5          */
 6         @ViewDebug.ExportedProperty
 7         float mRotationX = 0f;
 8
 9         /**
10          * The degrees rotation around the pivot point.
11          */
12         @ViewDebug.ExportedProperty
13         float mRotation = 0f;
14
15         /**
16          * The amount of translation of the object away from its left property (post-layout).
17          */
18         @ViewDebug.ExportedProperty
19         float mTranslationX = 0f;
20
21         /**
    /**
     * The degrees that the view is rotated around the vertical axis through the pivot point.
     *
     * @see #getPivotX()
     * @see #getPivotY()
     * @see #setRotationY(float)
     *
     * @return The degrees of Y rotation.
     */
    public float getRotationY() {
        return mTransformationInfo != null ? mTransformationInfo.mRotationY : 0;
    }
所以我们的first函数 是肯定可以执行成功的。

然后我们来看second函数。
anim.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal = (Float) animation.getAnimatedValue();
                view.setAlpha(cVal);
                view.setScaleX(cVal);
                view.setScaleY(cVal);
            }
        });
着重看这里,其实也就猜到了,对于第二种函数的属性动画调用来说, 我们是自己去控制的。
  float cVal = (Float) animation.getAnimatedValue();
                view.setAlpha(cVal);
                view.setScaleX(cVal);
                view.setScaleY(cVal);

这边取得值以后 就自己更改v的属性了~~~很容易理解。

所以实际上这里的代码 还可以这么写

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "tttt", 1.0F, 0.0F)
.setDuration(500);

那个tttt 还可以改成你任意想改的名字 对结果没有影响,因为最终是我们手动用回调函数去更改view的属性的,这个过程是我们自己写的,所以这里名字可以随便写,而first函数 则不可以 因为是系统自己通过反射去调用set get方法的,所以传值的时候要注意~~

最后一个函数 third函数 其实就是把系统里面自己实现的过程给单拿出来 罢了 不信我们可以跟踪源代码

ObjectAnimator 里的这个函数
/**
     * Constructs and returns an ObjectAnimator that animates between float values. A single
     * value implies that that value is the one being animated to. Two values imply a starting
     * and ending values. More than two values imply a starting value, values to animate through
     * along the way, and an ending value (these values will be distributed evenly across
     * the duration of the animation).
     *
     * @param target The object whose property is to be animated. This object should
     * have a public method on it called <code>setName()</code>, where <code>name</code> is
     * the value of the <code>propertyName</code> parameter.
     * @param propertyName The name of the property being animated.
     * @param values A set of values that the animation will animate between over time.
     * @return An ObjectAnimator object that is set up to animate between the given values.
     */
    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
        anim.setFloatValues(values);
        return anim;
    }
然后继续跟。
 /**
     * Sets the values, per property, being animated between. This function is called internally
     * by the constructors of ValueAnimator that take a list of values. But an ValueAnimator can
     * be constructed without values and this method can be called to set the values manually
     * instead.
     *
     * @param values The set of values, per property, being animated between.
     */
    public void setValues(PropertyValuesHolder... values) {
        int numValues = values.length;
        mValues = values;
        mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
        for (int i = 0; i < numValues; ++i) {
            PropertyValuesHolder valuesHolder = (PropertyValuesHolder) values[i];
            mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
        }
        // New property/values/target should cause re-initialization prior to starting
        mInitialized = false;
    }
  @Override
    public void setFloatValues(float... values) {
        if (mValues == null || mValues.length == 0) {
            // No values yet - this animator is being constructed piecemeal. Init the values with
            // whatever the current propertyName is
            if (mProperty != null) {
                setValues(PropertyValuesHolder.ofFloat(mProperty, values));
            } else {
                setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
            }
        } else {
            super.setFloatValues(values);
        }
    }
然后我们third函数里面调用的方法

ofPropertyValuesHolder
 /**
     * Constructs and returns an ObjectAnimator that animates between the sets of values specified
     * in <code>PropertyValueHolder</code> objects. This variant should be used when animating
     * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
     * you to associate a set of animation values with a property name.
     *
     * @param target The object whose property is to be animated. Depending on how the
     * PropertyValuesObjects were constructed, the target object should either have the {@link
     * android.util.Property} objects used to construct the PropertyValuesHolder objects or (if the
     * PropertyValuesHOlder objects were created with property names) the target object should have
     * public methods on it called <code>setName()</code>, where <code>name</code> is the name of
     * the property passed in as the <code>propertyName</code> parameter for each of the
     * PropertyValuesHolder objects.
     * @param values A set of PropertyValuesHolder objects whose values will be animated between
     * over time.
     * @return An ObjectAnimator object that is set up to animate between the given values.
     */
    public static ObjectAnimator ofPropertyValuesHolder(Object target,
            PropertyValuesHolder... values) {
        ObjectAnimator anim = new ObjectAnimator();
        anim.mTarget = target;
        anim.setValues(values);
        return anim;
    }

最终也是通过 setValues 这个方法来做的。

一目了然~~


				
时间: 2024-08-12 23:35:54

Android自定义view教程03---Android 属性动画 详解的相关文章

Android自定义view教程01-------------Android的Frame动画详解

本系列博文 最终的目的是能教会大家自己实现比较复杂的android 自定义控件.所以知识点不仅仅局促在自定义view本身上面.实际上现在github上一些做的比较出色的自定义控件 大部分都是由三个部分组成 第一:动画 第二:自定义view 第三:触摸滑动控制.所以我们这个系列也是由动画作为开篇.最终会带着大家分析几个github上比较出色的自定义控件. Android 的frame动画是比较简单基础的内容,在以往的2.x 3.x版本很多人都会去使用这个 来作为loading 图的实现方法.但是最

Android自定义view教程04-------------自定义属性动画

不太会美工,所以随便写了个菜单打开关闭的动画,主要是教会大家如何使用属性动画,可以这么说 学会属性动画 前面的fream动画和tween动画可以不用看了,因为他们2能做的,属性动画也能做, 他们2不能做的,属性动画也能做. 直接上代码吧,注释写的还算详细. 主activity代码 实际上没啥好看的,主要就是使用了dialogfragment,没有用dialog,因为谷歌后来推荐 我们使用这个dialogfragment,而且这个确实比dialog要优秀方便很多. package com.exam

属性动画详解一(Property Animation)

效果图: Android动画有两类: 1.View Animation(Frame Animation,Tween Animation) 2.Property Animation 其中,上述效果是用第二类属性动画做的. 什么是属性动画? 通俗的说,属性动画就是在一定的时间内,按照一定的规律来改变对象的属性(该属性对于该对象应该是从形态(大小,位置等)上可以感受到的),从而是对象展现出动画的效果. 作用:可以定义动画来改变对象的属性( You can define an animation to

Android自定义view教程05--自定义view的基础知识之LayoutInflater详解

前面的教程我们讲了一下android的动画 的使用,尤其是着重讲解了属性动画的使用.那么这章开始我们将会讲一下android 自定义view的一些基础知识.帮助大家理解. 首先我们来关注一下LayoutInflater这个类,经常使用开源控件的人对这个类应该很熟悉了,但是很少有人能把这个类讲明白 用清楚,今天我们就来深挖一下这个类. 首先我们定义一个button.xml 和button2.xml 1 <?xml version="1.0" encoding="utf-8

android自定义View之(四)------一键清除动画

1.前言: 自己也是参考别人的一些自定义view例子,学习了一些基本的自定义view的方法.今天,我参考了一些资料,再结合自已的一些理解,做了一个一键清除的动画.当年,我实现这个是用了几张图片,采用Frame anination的方式来实现,但是这个方法,不灵活,并且占资源,下面,我就采用自定义view的方法来实现这个功能. 2.效果图: 3.具体详细代码 3.1 \res\values\attrs_on_key_clear_circle_view.xml <resources> <de

Android自定义view教程06--Activity的绘制流程简单分析(基于android 4.0源码进行分析)

要明白这个流程,我们还得从第一部开始,大家都知道 在activity里面 setcontentview 调用结束以后 就可以看到程序加载好我们的布局文件了,从而让我们在手机上看到这个画面. 那么我们来看一下这个源码是如何实现的. 1 /** 2 * Set the activity content from a layout resource. The resource will be 3 * inflated, adding all top-level views to the activit

Android自定义View绘图实现拖影动画

前几天在"Android绘图之渐隐动画"一文中通过画线实现了渐隐动画,但里面有个问题,画笔较粗(大于1)时线段之间会有裂隙,我又改进了一下.这次效果好多了. 先看效果吧: 然后我们来说说基本的做法: 根据画笔宽度,计算每一条线段两个顶点对应的四个点,四点连线,包围线段,形成一个路径. 后一条线段的路径的前两个点,取(等于)前一条线段的后两点,这样就衔接起来了. 把Path的Style修改为FILL,效果是这样的: 可以看到一个个四边形,连成了路径. 好啦,现在说说怎样根据两点计算出包围

Android 属性动画 详解

认识属性动画 传统动画Animation平移方法的实现 TranslateAnimation animation = new TranslateAnimation(x轴初始位置,x轴终止位置,y轴初始位置,y轴终止位置); animation.setDuration(1000);//设置持续时间,ms单位 animation.setFillAfter(true);//设置动画结束后状态,true为保持最终状态 imageView.startAnimation(animation);//为控件添加

Android:属性动画详解

(一)简介 属性动画是Android 3.0中提供了新功能,便于对任意元素进行"平滑的过渡".众所周知,Android 之前提供的补间动画如AlphaAnimation.TranslateAnimation等都只能应用在View上,并且几乎没有任何可扩展的地方.并且,使用原来的动画无法实现颜色渐变效果,算是一个遗憾. 属性动画彻底打破了这种设计方式,不再将这些动画强制的放在View上,而是仅仅产生一系列的值,由开发人员自行使用这些值.例如,属性动画可产生1-0平滑过渡的值,把这些值应用