关于android滑屏菜单和tab菜单实现
前言
Android5.0的改版涉及到滑屏菜单以及tab菜单.关于滑屏菜单的实现网上有很多的实现方案.大多都是继承实现ViewGroup,并对Touch事件进行拦截和处理.这里我的实现方式并不是如此.我仅仅是将界面的动画部分封装成一个控制类,来对menu的各种事件进行处理.这种方式是轻量级的实现.比起继承的封装来得简便,但缺乏整体性.至于tab菜单这里并不是使用系统的TabHost,而是封装了一个TabGroup的控件,并且一个ActivityGroup来实现一个界面部分.
一、SlidingMenuHelper
SlidingMenuHelper主要是用来处理滑动动画的帮助类,最核心的也即是对动画的处理,剩下的界面部分依然是交还给调用方自行处理,这样做的好处在于1.轻量级的封装;2.界面依然按照原有的方式布局,不需要关注滑动效果,有利于界面的升级.
下面就分析一下动画部分.这里其实是通过View的layout的方法,让界面滑动到指定的位置,这个动画由一个TranslateAnimation来实现.通过计算控件的位置和滑动的目标位置达到控制动画过程.
由于这种方式极易被View.requestLayout()方法复原了偏移的位置,所以要在菜单view上treeView注册一个OnGlobalLayoutListener,通过onGlobalLayout的回调使得在requestLayout 之前就把菜单强制滑到指定位置.参考代码如下:
TranslateAnimation translateAnimation = null;
if (isMenuClicked) {
panelSliding.layout(0, panelSliding.getTop(), panelSliding.getWidth(), panelSliding.getBottom());
if(isShowAnimation){
translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, mMenuWidth, Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
}
} else {
panelSliding.layout(mMenuWidth, panelSliding.getTop(), mMenuWidth + panelSliding.getWidth(), panelSliding.getBottom());
if(isShowAnimation){
translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, -mMenuWidth, Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
}
}
二、Tab
android系统提供的TabHost和TabActivity也是可以实现tab的效果,但是这样组合被限定了很多,需要自定义修改的对方也很多,所以这2者之间的是强制依赖关系.并且5.0的界面中有很多处会用到tab这样的控件.基于上诉的情况,就分别实现了一个TabGroup和基类AbstractActivityGroup.这2个之间是弱耦合的.
TabGroup,最主要的是由RadioGroup来实现的.并且动态的注册tab.依据注册的tab来生成界面.参考代码如下:
AbstractActivityGroup自然是继承了ActivityGroup,最主要的是是间接的处理了LocalActivityManager和关ContentView部分.并且通过反射的方式修复了Destroy Activity的一个bug.参考代码如下: