android 软软的动画弹出菜单,基于Facebook的Reb
Hello,郭某又厚颜无耻的来码水文了,年终将至,又要被别人家程序猿的年终刷屏(年终奖和我有个Context关系(ノಠ益ಠ)ノ彡┻━┻)。所以,今天就让我们聊一点有意思♂的东西吧<( ̄ˇ ̄)/:“软软“的弹出菜单,一戳就破。没错,今天的片头就是这么短,此短非彼短,因为下面也很短。
︿( ̄︶ ̄)︿我是路过的DEMO : https://github.com/CarGuo/AnimationMenu
rebound
安利Facebook开源的弹簧动画库,模拟物理弹簧的效果,让直男♂的你从此软下来,产品经理再也不需要担心交互过硬了(✿◡‿◡)。
rebound模拟的是物理效果,这里主要是有两个关键点:Tension(拉力系数)、Friction(摩擦系数)。Tension越大♀,弹性效果就越大,很符合逻辑是吧( ̄o ̄) ;Friction越大,受到的阻力就会越大,弹性效果就会降低。这里注意的是,弹性虽好,但摩擦力也是必须的哟,学过物理的你应该知道,没有摩擦力,根本停不下来啊,摩擦力太大,又进不···呸呸呸,又弹性不好。
下方是facebook官方的demo,使用默认的F和T系数,创建一个Spring ,通过设置开始\接结束的系数,在监听过程中通过getCurrentValue,设置你想要的移动\放大\透明度等等效果,来实现你的动画,感觉是不是很ValueAnimation,简单易上手。
有兴趣的可以去rebound下载官方demo,如果发现官方demo跑不来,可以试试我fork修改后的demo哟:https://github.com/CarGuo/rebound
// Create a system to run the physics loop for a set of springs.
SpringSystem springSystem = SpringSystem.create();
// Add a spring to the system.
Spring spring = springSystem.createSpring();
// Add a listener to observe the motion of the spring.
spring.addListener(new SimpleSpringListener() {
@Override
public void onSpringUpdate(Spring spring) {
// You can observe the updates in the spring
// state by asking its current value in onSpringUpdate.
float value = (float) spring.getCurrentValue();
float scale = 1f - (value * 0.5f);
myView.setScaleX(scale);
myView.setScaleY(scale);
}
});
// Set the spring in motion; moving from 0 to 1
spring.setEndValue(1);
实现动画弹出框
进入正题:
1、首先我们定义一个布局,包含四个圆形TAB,让它们呈现如下图效果。然后把它们都设置为GONE。
2、创建一个Spring用于执行动画。
- 这里我们使用的是
SpringChain
,可以自定义我们想要的拉力和摩擦力系数,从左到右是主拉力,主摩擦力,辅助拉力,辅助摩擦力。 - 根据TAB的个数,我们对每一个View通过springChain.addSpring添加到队列中,并设置对应的监听。
- setCurrentValue设置初始化的开始数据为父布局的高度,这样每一个item就可以从屏幕底部开始弹出。
- springChain.setControlSpringIndex(0).getControlSpring().setEndValue(0);设置起主导作用的是第一个tab,最后的终止数据是0,也就是原来所在的位置。
- 在onSpringUpdate通过getCurrentValue换算出tab的位置和大小。
看下面,上面一堆废话,那个傻X说了那么多,哇塞,代码好简单啊(o)/,是不是觉得站在巨人的肩膀上,很自豪啊。收回动画就是把弹出的反过来即可,妥妥的。
SpringChain springChain = SpringChain.create(40, 6, 50, 7);
for (int i = 0; i < list.size(); i++) {
final View view = list.get(i);
springChain.addSpring(new SimpleSpringListener() {
@Override
public void onSpringActivate(Spring spring) {
super.onSpringActivate(spring);
view.setVisibility(VISIBLE);
}
@Override
public void onSpringUpdate(Spring spring) {
view.setTranslationY((float) spring.getCurrentValue());
float scale = (1 + 2 * (float) spring.getCurrentValue() / mainView.getHeight());
view.setScaleX(scale);
view.setScaleY(scale);
}
});
}
List<Spring> springs = springChain.getAllSprings();
for (int i = 0; i < springs.size(); i++) {
springs.get(i).setCurrentValue(mainView.getHeight());
}
springChain.setControlSpringIndex(0).getControlSpring().setEndValue(0);
最后我们额外来个副菜,既然弹出\收起都有效果,那么“碰”起来也要有效果才对,这里我们就参考微博的菜单,在点击时候执行最后的动画效果。
这个相对更加简单,我们使用系统的AnimationSet ,将点击的TAB放大和透明化动画一起执行,将其他的TAB同时缩小和透明化,动画结束时让tab隐藏起来,这样一个完整的菜单动画就结束啦。(。・・)ノ是不是好短啊,都说好短啦。
AnimationSet animationSet = new AnimationSet(true);
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
animationSet.setInterpolator(new AccelerateInterpolator());
animationSet.setDuration(200);
animationSet.setFillAfter(false);
animationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.setVisibility(GONE);
ButtonClickLogin(view);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(animationSet);
最后说两句
两句。
瞅完了吧