Android动画(五)PropertyValuesHolder和KeyFream使用

    技术2022-07-13  91

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

    概述先看看本篇要实现的效果吧PropertyValuesHolderofInt(),ofFloat()和ofObject() KeyFreamKeyframe.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类型的,所以这里类型只能使用character set后边的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.

    Processed: 0.024, SQL: 9