Android动画(五)PropertyValuesHolder和KeyFream使用

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

概述

前几篇给大家介绍了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.

猜你喜欢

转载自blog.csdn.net/weixin_44819566/article/details/107080585
今日推荐