记录一些设计上的事儿
不知道今天能不能写完一篇完整的文章,除非没人打扰我。
书归正传!
前段时间给人家做了一个应用,有一个类似于展示详情信息的界面,如下图所示,我想说一下关于动画对象的事,
在应用中使用动画时非常常见的,我自己比较喜欢加一些小的动画来让应用更加的生动,调节一下气氛。现在用的最多的Animator这个对象,之前用Animation,慢慢的被淘汰了,因为它只能改变试图,却无法真正的改变对象的属性(表面上是动了)。
所以,Animator是我不二的选择。
第一次用这个对象的时候觉的特别的好用,又一次我把一个物体从屏幕的上面移动到了下边,而且物体的属性是实实在在的被改变了,然后需求让我再一次的让物体回到原位(还是以动画的形式,相当于倒着播放一次),于是我开始找back()或者reverse()这样的方法,但是,没有!我还没有放弃,我查看了和Animator相关的类,包括AniamtorSet,Aniamtor.Builder等,都好像没有直接可以达到目的的方法,这样我该放弃了,一定是要重新创建animator对象的。
上面一次动画的显示牵动了6个对象,也就是创建出6个Animator对象一起执行或在某个地方触发执行,当列表被推到上面后,动画执行结束,当列表被拉下后,之前的动画要被重新反着执行一次。
思考:
1、6个对象,起码要有6组动画起始数据要保存,难道都要作为成员变量放在一个类里面?起名字就够累的。
2、创建了6个动画对象在所难免,但是每次动画都要重新创建一次吗?尤其是镜像返回的动画,可不可以重复利用创建好的动画对象,把起始和结束的值相互换一下位置就可以了呢?
带着以上的问题,为了让代码更加的紧凑和有良好的设计感,我做了些封装,只是封装和一些常用的设计。
首先,我设计了一个类,起名叫做AnimtorsHolder,
首先它是个单例,里面只有两个私有成员变量,一个是它自己本身,另外一个是ArrayList容器,里面放的是AnimatorObject,你们都见过ObjectAnimator,但是没加过它吧,顺便多一嘴,ValueAnimator要比ObjectAnimator更加节省资源(播放动画卡不卡很明显)多用ValueAnimator吧。这个AnimatorObject也是我设计的类,放到后面说。
再看AnimtorsHolder类,有四个公有方法,getInstance返回一个单例,add方法是向ArrayList里添加对象,只用add的是(Object obj),看到这里应该知道用到那几个设计模式了吧,嘿嘿。
public void add(AnimatorObject object) {
animatorObjects.add(object);
}
getAnimators方法
public ArrayList<Animator> getAnimators() {
ArrayList<Animator> animators = new ArrayList<Animator>();
for (AnimatorObject object : animatorObjects) {
animators.add(object.getAnimator());
}
return animators;
}
这个方法其实就是创建一个装Animator的容器,将外部的成员容器遍历一遍从AnimatorObject获取到Animator对象
getBackAnimators(),一样,先创建一个装Animator的容器,将外部的成员容器遍历一遍从AnimatorObject获取到Animator对象,并且获取到起始和结束的值(改进,把这些值放入到队列里,这样正序倒序随意取)反着赋值,这里由于不确定是Int还是Float,为此还判断了一下,这样处理过后,容器里存放的Animator对象的属性就是反着的了,并且通过这样的设计,也没有重新创建Aniamtor对象。
public ArrayList<Animator> getBackAnimators() {
ArrayList<Animator> animators = new ArrayList<Animator>();
for (AnimatorObject object : animatorObjects) {
ValueAnimator animator = (ValueAnimator) object.getAnimator();
Object start = object.getStart();
Object end = object.getEnd();
if(start instanceof Integer) {
animator.setIntValues((int)end, (int)start);
} else if (start instanceof Float){
animator.setFloatValues((float)end, (float)start);
}
animators.add(animator);
}
return animators;
}
看如何使用的
/*初始化AnimatorsHolder*/
animators = AnimatorsHolder.getInstance();
/*创建一个动画对象*/
ValueAnimator moveY = ValueAnimator.ofInt(start, end);
/*调用AnimatorsHolder的add方法,并且创建一个AnimatorObject对象他是个泛型(改进:应该使用动态参数的设计)*/
animators.add(new AnimatorObject<Integer>(moveY, start, end));
/*播放动画*/
AnimatorSet palySet = new AnimatorSet();
palySet.setDuration(300);
palySet.playTogether(animators.getAnimators());
palySet.start();
如果想把之前创建的动画反着播一遍,这样。
AnimatorSet palySet = new AnimatorSet();
palySet.setDuration(300);
palySet.playTogether(animators.getBackAnimators());
palySet.start();
就这样简单的几句就搞定。是不是很节省资源。