侧滑菜单自定义SlideMenu

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wdx_1136346879/article/details/86292061

=侧滑菜单========

在这里插入图片描述

SlidingMenu 是GitHub上的一个开源项目,用来实现SlidingMenu的菜单效果。
Sliding Menu的是一种比较新的设置界面或配置界面效果,在主界面左滑或者右滑出现设置界面,能方便的进行各种操作
,还是GitHub上的开源项目SlidingMenu提供了最佳的实现:定制灵活、各种阴影和渐变的滑动效果也很
左滑和右滑出现菜单,用一个参数就可以简单配置。
menu.setMode(SlidingMenu.LEFT);

这是一个开源库,而不是一个完整的项目,把它作为libary引入到你自己的工程里,简单配置一下就可以实现SlidingMenu的效果。
1.自定义SlideMenu,继承自ViewGroup

2.编写menu和main界面的布局,然后include到SlideMenu中,作为它的子view

3.在onFinishInflate方法中通过getChildAt(0)来初始化menuView和mainView对象

4.在onSizeChanged方法中获取menuView和mainView的宽高

5.自己实现onMeasure方法,主要了解测量规则MeasureSpec如果创建,以及三种测量mode的含义

6.由于自己实现onMeasure方法太麻烦和繁琐,最后将SlideMenu继承自FrameLayout,原因如下:
a.因为FrameLayout帮我们实现了onMeasure方法,不需要我们自己实现
b.因为FrameLayout代码最少,在四大布局中属于轻量级

7.由于FrameLayout是按照自己的方式实现onLayout方法,而我们的需求是将menuView放在屏幕左边,
所以需要自己重写onLayout方法:
menuView.layout(-menuWidth, 0, 0, menuHeight);
mainView.layout(0, 0, mainWidth, menuHeight);

8.当TouchMove的时候让SlideMenu跟随手指滑动
tip1:在ViewGorup中让子view移动的方法:
layout(l,t,r,b);
offsetTopAndBottom(offset)和offsetLeftAndRight(offset);
scrollTo和scrollBy;

tip2:scrollTo和scrollBy表示的不是view本身的移动,而是指屏幕的移动
a.在onTouchEvent方法中计算出手指移动的距离
b.根据手指移动的距离和当前屏幕已经滚动的scrollX的坐标算出新的scrollX:
int newScrollX = (int) (getScrollX()-deltaX);
c.对SlideMenu进行左边和右边的限定
if(newScrollX<-menuWidth){
newScrollX = -menuWidth;//限制左边
}
if(newScrollX>0){
newScrollX = 0;//限制右边
}

9.当TouchUp的时候缓慢滑动SlideMenu到指定位置
tip3:Scroller: 是用来模拟滚动的,模拟了一个滚动的流程,然后在滚动过程中也计算好了当前应该
滚动的scrollX和scrollY。
我们需要在它的执行过程中获得当前的scrollX和scrollY,然后自己去scrollTo(scrollX,scrollY);
a.使用Scroller处理缓慢滚动:
scroller.startScroll(getScrollX(), 0, 0-getScrollX(), 0,400);
// Invalidate to request a redraw
invalidate();
b.在computeScroll方法中不断获取当前的currX和currY,然后自己去scrollTo
if(scroller.computeScrollOffset()){//如果返回true,表示动画没有结束,反之就结束
scrollTo(scroller.getCurrX(), scroller.getCurrY());
invalidate();
}

10.此时出现滑动bug,当在menu中的ScrollView中水平滑动时无法滑动SlideMenu,
a.根据触摸事件的传递机制分析原因,传递机制详情见图
b.只要我们拦截触摸事件,就会将Event传给onTouchEvent,从而可以滑动
c.但是我们要在一定条件下才能拦截,在move的方向偏于水平方向的时候拦截
d.在onInterceptTouchEvent方法中计算x和y方向的移动距离,并比较是偏于水平还是垂直

猜你喜欢

转载自blog.csdn.net/wdx_1136346879/article/details/86292061