最近看到QQ空间 新浪微博....好多应用底部导航栏都有加号点击弹出菜单,于是就写了一个demo,来给没做过这个功能的小伙伴一个参考,希望对大家有所帮助,demo中的图片均来源于Qzone 仅作为学习交流使用。
先来看一下效果(gif图是手机屏幕投影到电脑上录制下来的效果不太好,在手机上很流畅)
一、分析
要想实现这个效果 首先我们需要一个半透明的 popupWindow (或其他的实现方式)
(1) 在popupWindow 的layout层布局加上一个半透明的背景
android:background="#e0ffffff"
(2) 我们把popupWindow 封装到 PopupMenuUtil 这个工具类里边 ,activity 里只需要在导航栏加号的点击事件中加上一句调用就可以了 其他的都交给popupWindow来处理
@Override
public void onClick(View v) {
PopupMenuUtil.getInstance()._show(context, ivImg);
}
(3) popupWindow 需要有一个和导航栏中一模一样的加号, 当弹起的时候对其进行覆盖,并且弹窗的时候执行popupwindow中加号图片135度的旋转,以及所有菜单从屏幕最底部通过属性动画平移上来。
二、关键代码
(1) 当popupWindow 弹起的时候 加号执行的动画
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivBtn, "rotation", 0f, 135f);
objectAnimator.setDuration(200);
objectAnimator.start();
(2) 每一个menu 执行的动画方法
/* * 启动动画
* @param view view
* @param duration 执行时长
* @param distance 执行的轨迹数组
*/
private void _startAnimation(View view, int duration, float[] distance) {
ObjectAnimator anim = ObjectAnimator.ofFloat(view, "translationY", distance);
anim.setDuration(duration);
anim.start();
}
distance 为执行属性动画的数组
new float[]{bottom, 60, -30, -20 - 10, 0}; //bottom为距离屏幕底部的距离
执行动画的顺序的数组一样,时间不一样就可以实现菜单平移的视觉差效果
(3) 同样popupwindow关闭的时候加号按钮也需要逆时针旋转135度的动画 菜单也需要平移到底部的动画
/**
*关闭 popupWindow执行的动画
*/
public void _rlClickAction() {
if (ivBtn != null && rlClick != null) {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ivBtn, "rotation", 135f, 0f);
objectAnimator.setDuration(300);
objectAnimator.start();
_closeAnimation(llTest1, 300, top);
_closeAnimation(llTest2, 200, top);
_closeAnimation(llTest3, 200, top);
_closeAnimation(llTest4, 300, top);
_closeAnimation(llTest5, 300, bottom);
_closeAnimation(llTest6, 200, bottom);
_closeAnimation(llTest7, 200, bottom);
_closeAnimation(llTest8, 300, bottom);
rlClick.postDelayed(new Runnable() {
@Override
public void run() {
_close();
}
}, 300);
}
}
需要注意的是:
(1) popupWindow 需要延迟300毫秒在关闭(也就是所有动画执行完毕) 否则立即关闭是看不到动画效果的。
(2) 需要在activity 里边监听返回键 否则当popupWindow 弹起之后,也是看不到动画的关闭效果的。
@Override
public void onBackPressed() {
// 当popupWindow 正在展示的时候 按下返回键 关闭popupWindow 否则关闭activity
if (PopupMenuUtil.getInstance()._isShowing()) {
PopupMenuUtil.getInstance()._rlClickAction();
} else {
super.onBackPressed();
}
}
activity中监听返回键的响应 判断是否正在展示popupWindow 如果正在展示执行关闭方法 否则直接执行finish()方法
为了看出效果主界面写了一个简单模仿qzone的列表 如果不需要可以直接看这个类PopupMenuUtil
<a href="https://github.com/MjCodeTinker/WindowMenuDemo">github demo地址</a>
<a href="http://download.csdn.net/detail/mj_air/9666981">csdn demo地址</a>