自己去定义一个SlidingMenu类继承自HorizontalScrollView,主要是在滑动过程中menu和content部分变化的一些动画,透明度啊,缩放之类的。
这里还要导入nineoldandroids-2.4.0.jar.
public class SlidingMenu extends HorizontalScrollView { private LinearLayout mWapper; private ViewGroup mMenu; private ViewGroup mContent; private int leftx; private int mScreenWidth; private int mMenuWidth; private int mMenuLeftPadding = 80; private boolean once = false; private boolean isOpen = false; /** * by lijun * 未使用自定义属性时使用 */ public SlidingMenu(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SlidingMenu(Context context, AttributeSet attrs,int defStyle) { // TODO Auto-generated constructor stub super(context, attrs,defStyle); //获取我们定义的属性 TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SildingMenu, defStyle, 0); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); switch (attr) { case R.styleable.SildingMenu_rightPadding: mMenuLeftPadding =a.getDimensionPixelOffset(attr, (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 80, context .getResources().getDisplayMetrics()));//dp转换为px break; } } a.recycle(); WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); mScreenWidth = outMetrics.widthPixels; //获取屏幕的宽高 } public SlidingMenu(Context context) { //new的时候调用 // TODO Auto-generated constructor stub super(context,null); } /** * by lijun * 设置子View的宽高设置自己的宽高 * @return */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub if(!once) { mWapper = (LinearLayout)getChildAt(0); mMenu = (ViewGroup) mWapper.getChildAt(0); mContent = (ViewGroup) mWapper.getChildAt(1); mMenuWidth = mMenu.getLayoutParams().width = mScreenWidth - mMenuLeftPadding; mContent.getLayoutParams().width = mScreenWidth; once = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * by lijun * 通过设置偏移量,将menu隐藏 */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub super.onLayout(changed, l, t, r, b); if(changed) { this.scrollTo(mMenuWidth, 0); } } @Override public boolean onTouchEvent(MotionEvent ev) { // TODO Auto-generated method stub int action = ev.getAction(); int xxxx = (int) ev.getX(); switch (action) { case MotionEvent.ACTION_DOWN: leftx = xxxx; return true; case MotionEvent.ACTION_UP: int scrollX = getScrollX(); int lable = scrollX - leftx; if(lable>0) { Log.i("aaaaaaaaa", scrollX+"okokokokok"+leftx); if(scrollX >= mMenuWidth/2) { this.smoothScrollTo(mMenuWidth, 0); //带有动画效果的移动 isOpen = false; } else { this.smoothScrollTo(0, 0); isOpen = true; } return true; } else { this.smoothScrollTo(0, 0); } default: break; } return super.onTouchEvent(ev); } /** * by lijun * 打开菜单 */ public void openMenu() { if(isOpen) return; this.smoothScrollTo(0, 0); isOpen = true; } public void closeMenu() { if(!isOpen) return; this.smoothScrollTo(mMenuWidth, 0); isOpen = false; } /** * by lijun * 切换菜单 */ public void toggle() { if(isOpen) { closeMenu(); }else { openMenu(); } } /** * by lijun * 滚动发生时 */ protected void onScrollChanged(int l,int t,int oldl,int oldt) { super.onScrollChanged(l, t, oldl, oldt); float scale = l*1.0f/mMenuWidth; //1-0 //调用属性动画 ViewHelper.setTranslationX(mMenu,mMenuWidth*scale); /**主要代码部分 * by lijun * 实现抽屉式拖拉 * 区别一:内容区域1.0-0。7的缩放效果 * scale:1.0-0.0 * 0.7+0.3*scale * 区别二:菜单的偏移量需要修改 * 区别三:菜单的显示时有缩放以及透明度变化 * 缩放:0.7-1.0 * 1.0-scale*0.3 * 透明度0.6-1.0 * 0.6+0.4*(1-scale) */ float leftScale = 1.0f-0.3f*scale; float leftAlpha = 0.5f+0.4f*(1-scale); float rightScale = 0.7f+0.3f*scale; ViewHelper.setTranslationX(mMenu, mMenuWidth*scale); ViewHelper.setScaleX(mMenu, leftScale); ViewHelper.setScaleY(mMenu, leftScale); ViewHelper.setAlpha(mMenu, leftAlpha); ViewHelper.setPivotX(mContent, 0); ViewHelper.setPivotY(mContent, mContent.getHeight()/2); //获取中心点 ViewHelper.setScaleX(mContent, rightScale); ViewHelper.setScaleY(mContent, rightScale); }}