AI智能
改变未来

Android动画(五)PropertyValuesHolder和KeyFream使用

今天给大家介绍PropertyValuesHolder和Keyframe,在动画中也是属于比较重要的东西,请大家细品,接下来步入主题

  • 概述
  • 先看看本篇要实现的效果吧
  • PropertyValuesHolder
  • ofInt(),ofFloat()和ofObject()
  • KeyFream
    • Keyframe.ofObject();

    概述

    前几篇给大家介绍了ObjectAnimator的ofInt(),ofFloat()ofObject()方法,这篇给大家带来ObjectAnimator.ofPropertyValuesHolder();方法的介绍和简单的使用

    先看看本篇要实现的效果吧

    PropertyValuesHolder

    介绍:
    PropertyValuesHolder类相当于一个动画容器,主要作用就是用来存放属性对应的值与属性的.他的作用和animatorSet()有点类似.大家吧他当做animatorSet()方法就好.不一样的地方就是ofPropertyValuesHolder()是ObjectAnimator的静态方法;

    有参构造

    • PropertyValuesHolder ofint = PropertyValuesHolder.ofInt(String propertyName, int… values)
    • PropertyValuesHolder offloat = PropertyValuesHolder.ofFloat(String propertyName, float… values)
    • PropertyValuesHolder ofObject = PropertyValuesHolder.ofObject(String propertyName, TypeEvaluator evaluator,
      Object… values)
    • PropertyValuesHolder ofKeyFream = PropertyValuesHolder.ofKeyfream(String propertyName, Keyframe… values)
    • 参数一:需要设置的动画属性
    • 参数二:可变参数,用来设置动画值,比如现在动画属性是\”scaleX\”,1代表本身不变,1.5则代表相对于X轴方法1.5倍,0.5则代表相对于X轴缩小0.5倍.以此类推

    ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(Object target,
    PropertyValuesHolder… values);

    参数一:需要设置的控件
    参数二:可变参数,可添加多个PropertyValuesHolder对象

    ofInt(),ofFloat()和ofObject()

    先来康康要实现的效果:


    这里就同时用到了:

    • ofObject()设置A-Z显示,
    • ofFloat()设置Y轴缩放,
    • ofInt()改变背景颜色

    先看看代码在一步一步讲解:

    PropertyValuesHolder TextTitle = PropertyValuesHolder.ofObject(\"TextTitle\",new MyEvaluator(), new Character(\'A\'), new Character(\'Z\'));PropertyValuesHolder backgroundColor = PropertyValuesHolder.ofInt(\"backgroundColor\",0xffff00ff,0xffffff00,0xff00ff00,0xff00f0f0);PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat(\"scaleY\",1.1f,1,5,1f,7f,1f);ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(myTextView, TextTitle,backgroundColor,scaleY);objectAnimator.setDuration(3000);objectAnimator.start();
    PropertyValuesHolder.ofObject(\"TextTitle\",new MyEvaluator(), new Character(\'A\'), new Character(\'Z\'));
    • 参数一介绍:

    这里使用到了ofObject()实现从A-Z依次显示,第一个参数中需要一个set方法,所以就必须先定义一个类,继承自TextView,实现setTextTitle()方法

    public class MyTextView extends TextView {public MyTextView(Context context) {super(context);}public MyTextView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}//因为A - Z依次显示的是char类型的,所以这里类型只能使用characterset后边的TextTitle就是ofObject()中的参数一;public void setTextTitle(Character c){setText(String.valueOf(c));}}

    因为咋们并没有对这个自定义View做什么,并且它是继承自TextView的,所以咋们就当做它是TextView使用即可.

    • 参数二介绍:
      前几篇讲过这个TypeEvaluator,这是一个加速器,这里就不在重复讲解了,如有需要可以点击 查看.Evaluator来进行了解.这里直接贴代码了.
    public class MyEvaluator implements TypeEvaluator<Character> {@Override			//当前的进度,  开始的值        结束的值public Character evaluate(float fraction, Character startValue,Character endValue) {int end = endValue;int start = startValue;int a = (int) (start + ( fraction * (end - start)));char b = (char) a;return b;}}公式:当前进度 = 最小值 + (进度 * (最大值 - 最小值))
    这个和ObjectAnimator.ofFloat(),ObjectAnimator.ofInt()用法完全相同,这里就不在讲解了PropertyValuesHolder backgroundColor = PropertyValuesHolder.ofInt(\"backgroundColor\",0xffff00ff,0xffffff00,0xff00ff00,0xff00f0f0);PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat(\"scaleY\",1.1f,1,5,1f,7f,1f);

    这里肯定有朋友有所疑问什么时候用ofInt(),什么时候用Float()呢?

    • 是动画属性的时候有用ofFloat()其余的都用ofInt(),什么是动画属性呢?,就比如旋转,移动,透明,缩放,这些用ofFloat(),除这些以外,比如设置个背景颜色\”backgroundColor\”就用ofInt().

    KeyFream

    KeyFream是关键帧的意思,通过key和value的形式,将值传入ofKeyFream(String propertyName, Keyframe… values)中.
    先看看要实现的效果:

    有参构造:

    • KeyFrame.OfFloat(String propertyName, Keyframe… values)
    • Keyframe scaleKeyframe = KeyFrame.OfFloat(String propertyName)
      通过scaleKeyframe.setValue()来设置Value

    咋们先看看KeyFrame.OfFloat()方法的源码注释:


    参数一:时间,用0到1之间的值表示,表示分数 整个动画持续时间的时间。
    参数二: 要设置的关键帧值

    咋们先定义11个keyFragme.ofFloat(),代表把所设置时间分为10份,每一份作对应的值.

    Keyframe scaleKeyframe = Keyframe.ofFloat(0f, 0);Keyframe scaleKeyframe1 = Keyframe.ofFloat(0.1f, 1.1f);Keyframe scaleKeyframe2 = Keyframe.ofFloat(0.2f, 1.2f);Keyframe scaleKeyframe3 = Keyframe.ofFloat(0.3f, 1.2f);Keyframe scaleKeyframe4 = Keyframe.ofFloat(0.4f, 1.1f);Keyframe scaleKeyframe5 = Keyframe.ofFloat(0.5f, 2f);Keyframe scaleKeyframe6 = Keyframe.ofFloat(0.6f, 1.2f);Keyframe scaleKeyframe7 = Keyframe.ofFloat(0.7f, 1.1f);Keyframe scaleKeyframe8 = Keyframe.ofFloat(0.8f, 1.1f);Keyframe scaleKeyframe9 = Keyframe.ofFloat(0.9f, 1.2f);Keyframe scaleKeyframe10 = Keyframe.ofFloat(1f, 1);PropertyValuesHolder scale = PropertyValuesHolder.ofKeyframe(\"scaleX\",scaleKeyframe, scaleKeyframe1, scaleKeyframe2, scaleKeyframe3, scaleKeyframe4,scaleKeyframe5, scaleKeyframe6, scaleKeyframe7, scaleKeyframe8, scaleKeyframe9, scaleKeyframe10);ObjectAnimator objectAnimator1 = ObjectAnimator.ofPropertyValuesHolder(tv, scale);objectAnimator1.setDuration(3000);objectAnimator1.start();

    来康康效果吧:

    这里可以看出,效果还是很明显的,咋们这里设置的动画时间是3s,在时间进行到一半(0.5)的时候,相对于X轴放大2倍.

    这里设置了11帧,如果设置1帧会出现什么情况呢?

    这里只设置在进度走40%的时候,变大2倍Keyframe scaleKeyframe4 = Keyframe.ofFloat(0.4f, 2f);

    来康康效果吧:

    可以看出,如果只设置一帧的话,会出现下标越界,那咋们继续,在加一帧,给他一个开始帧,和一个结束帧看看有什么效果吧:

    Keyframe scaleKeyframe4 = Keyframe.ofFloat(0.4f, 2f);Keyframe scaleKeyframe8 = Keyframe.ofFloat(0.8f, 1.1f);

    这里设置在40%的时候,X轴变大2倍,然后依次缩小到80%的时候,变化到1.1倍
    来看看效果~

    大家可以看到,如果这样设置的话,开始帧就是从40%处开始,并且结束的时候会返回到最开始的状态

    现在已经有2种情况需要注意:

    • 必须有2帧以上,开始帧和结束帧
    • 开始帧是从设置进度开始的而不是从0的进度开始

    我还想到一种情况,若开始帧不是0-1之间若>1会是什么效果呢?,接下来就带大家一起看看实验一下,看看效果吧:

    Keyframe scaleKeyframe4 = Keyframe.ofFloat(0.4f, 2f);Keyframe scaleKeyframe8 = Keyframe.ofFloat(0.8f, 1.1f);Keyframe scaleKeyframe9 = Keyframe.ofFloat(1f, 1f);Keyframe scaleKeyframe10 = Keyframe.ofFloat(2.5f, 3f);

    为了效果明显,我把最后一个设置为扩大三倍:

    很明显,设置的250%进度并没有效果,所以得出一下结论:

    • 必须有2帧以上,开始帧和结束帧
    • 开始帧是从设置进度开始的而不是从0的进度开始
    • 设置进度必须在0-1之间,否则会没有效果

    Keyframe.ofObject();

    先来看看实现的效果吧:

    直接上代码

    Keyframe objectKetframeA = Keyframe.ofObject(0, \'A\');Keyframe objectKetframeC = Keyframe.ofObject(0.3f, \'C\');Keyframe objectKetframeZ = Keyframe.ofObject(1f, \'Z\');PropertyValuesHolder textTitle = PropertyValuesHolder.ofKeyframe(\"TextTitle\", objectKetframeA, objectKetframeC, objectKetframeZ);textTitle.setEvaluator(new MyEvaluator());ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(myTextView, textTitle);objectAnimator.setDuration(3000);objectAnimator.start();

    其实他们的用法都基本很相似,这里的关键帧设置的是当进度走到30%的时候,显示C,然后在剩下的70%进度中走到Z,
    在效果图中也可以很明显的看到事实确实如此.这里的TextTitle和MyEvaluator()用过很多次,就不在重复啰嗦了.

    最后来完成咋们本篇开始的效果:

    直接上代码:

    Keyframe keyframe = Keyframe.ofFloat(0f, 0);Keyframe keyframe1 = Keyframe.ofFloat(0.1f, 20f);Keyframe keyframe2 = Keyframe.ofFloat(0.2f, -20f);Keyframe keyframe3 = Keyframe.ofFloat(0.3f, 40f);Keyframe keyframe4 = Keyframe.ofFloat(0.4f, -40f);Keyframe keyframe5 = Keyframe.ofFloat(0.5f, 20f);Keyframe keyframe6 = Keyframe.ofFloat(0.6f, -20f);Keyframe keyframe7 = Keyframe.ofFloat(0.7f, 40f);Keyframe keyframe8 = Keyframe.ofFloat(0.8f, -40f);Keyframe keyframe9 = Keyframe.ofFloat(0.9f, 20f);Keyframe keyframe10 = Keyframe.ofFloat(1f, 0);Keyframe scaleKeyframe = Keyframe.ofFloat(0f, 0);Keyframe scaleKeyframe1 = Keyframe.ofFloat(0.1f, 1.1f);Keyframe scaleKeyframe2 = Keyframe.ofFloat(0.2f, 1.2f);Keyframe scaleKeyframe3 = Keyframe.ofFloat(0.3f, 1.2f);Keyframe scaleKeyframe4 = Keyframe.ofFloat(0.4f, 2f);Keyframe scaleKeyframe5 = Keyframe.ofFloat(0.5f, 2f);Keyframe scaleKeyframe6 = Keyframe.ofFloat(0.6f, 1.2f);Keyframe scaleKeyframe7 = Keyframe.ofFloat(0.7f, 1.1f);Keyframe scaleKeyframe8 = Keyframe.ofFloat(0.8f, 1.1f);Keyframe scaleKeyframe9 = Keyframe.ofFloat(0.9f, 1.5f);Keyframe scaleKeyframe10 = Keyframe.ofFloat(1f, 1f);PropertyValuesHolder rotation = PropertyValuesHolder.ofKeyframe(\"rotation\",keyframe, keyframe1, keyframe2, keyframe3, keyframe4,keyframe5, keyframe6, keyframe7, keyframe8, keyframe9, keyframe10);PropertyValuesHolder scale = PropertyValuesHolder.ofKeyframe(\"scaleX\",scaleKeyframe, scaleKeyframe1, scaleKeyframe2, scaleKeyframe3, scaleKeyframe4,scaleKeyframe5, scaleKeyframe6, scaleKeyframe7, scaleKeyframe8,scaleKeyframe9, scaleKeyframe10);ObjectAnimator objectAnimator1 = ObjectAnimator.ofPropertyValuesHolder(tv, rotation,scale);objectAnimator1.setDuration(3000);objectAnimator1.start();

    我相信通过上面的讲解,这段代码还是能看明白的,本篇有点长,可能有讲的不到位的地方,请大家多多包涵,有大佬有不同意见,欢迎在评论区留言哦~

    参考文档:链接: 启舰.

    git地址:链接: langyangyang.

    赞(0) 打赏
    未经允许不得转载:爱站程序员基地 » Android动画(五)PropertyValuesHolder和KeyFream使用