Android仿Qzone底部导航栏加号弹出菜单

最近看到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 viewview *@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(); }

【Android仿Qzone底部导航栏加号弹出菜单】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
github demo地址
csdn demo地址

    推荐阅读