最近看了QQ新的侧滑,觉得很有意思,仿制了下,但在3.0以下就不适配,虽然有侧滑效果,但在点击时仍然是在旧的位置,这也是nineoldandroids的一个缺点。
一开始想过用Scroller,但是Scroller移动的只是内容,位置不变,这样无法把下层的菜单露出来,所以采用属性动画。
首先考虑清楚在什么情况下要拦截动作,是在从左向右滑动的时候,或者主界面X不为0的时候,这时候父控件就要拦截动作,并处理。
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean intercepted = false; int x = (int) ev.getX(); int y = (int) ev.getY(); final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: intercepted = false; break; case MotionEvent.ACTION_MOVE: int deltaX = x - mLastX; //认为是从左向右滑动 if((deltaX > 0 && deltaX > touchSlop) || mainLayout.getX() > 0) { return true; } else { return false; } case MotionEvent.ACTION_UP: intercepted = false; break; } mLastX = x; mLastY = y; return intercepted; }在这里因为我们没有拦截父控件的Down事件,所以如果子控件没有处理动作的话,也就是说如果没有ScrollView等可点击的View时,因为会触发父控件的onTouchEvent(),而我们返回true,这就导致父控件会处理接下来的动作,这时候move就不会触发onInterceptTouchEvent()函数了。
但是如果子控件有点击事件的,这时候并不会触发父控件的onTouchEvent(),而是触发子控件的onTouchEvent()。在move的时候,会调用父控件的onInterceptTouchEvent()函数,这时如果拦载了,即返回true,那么会先取消子控件的onTouchEvent(),即传入一个cancel动作。再调用父控件的onTouchEvent()函数。
拦截完动作后就处理动作了
@Override public boolean onTouchEvent(MotionEvent event) { int x = (int) event.getX(); int y = (int) event.getY(); int deltaX = x - mLastX; switch (event.getAction()) { case MotionEvent.ACTION_MOVE: if(mainLayout.getX() + deltaX <= 0) { mainTranslationX(0); childTranslationX(-screenWidth / 4); } else if(mainLayout.getX() + deltaX >= childWidth) { mainTranslationX(childWidth); childTranslationX(0); } else if(mainLayout.getX() > 0) { mainTranslationX(mainLayout.getX() + deltaX); childTranslationX(childMenuLayout.getX() + deltaX / 3); } else { //认为是从左向右滑动 if(deltaX > 0 && deltaX > touchSlop) { mainTranslationX(mainLayout.getX() + deltaX); childTranslationX(childMenuLayout.getX() + deltaX / 3); } } break; case MotionEvent.ACTION_UP: if(mainLayout.getX() <= screenWidth / 4) { mainTranslationX(0); childTranslationX(-screenWidth / 4); } else if(mainLayout.getX() > screenWidth / 4 ) { mainTranslationX(childWidth); childTranslationX(0); } break; default: break; } mLastX = x; mLastY = y; return true; }这就是目前所做的侧滑流程。继续加油。