Android-ui效果自定义控件UI效果仿写

悬浮导航栏StickyNavLayout的实现--如何实现滑动不

2016-05-27  本文已影响1452人  皮球二二

致敬鸿洋,这篇文章是基于他的项目改造而成的

本次主题将分成3个部分进行讲解,前2部分基本上是对鸿洋的代码解读以及一些小bug的处理,第三部分是针对鸿洋Android-StickyNavLayout不支持的功能进行优化处理。本文对应的项目地址在Github

对上篇文章还有印象的同学,你们肯定会有一个问题:我可不可以每次不要停顿,直接向下滑动或者向上滑动?现在,我就告诉你如何去实现。
我们知道dispatchTouchEvent是用来进行事件分发的,他说发down,那边该层的onInterceptTouchEvent就乖乖的发down,说发move,那边就跟着发move。诸位是不是有想法了!!!

来一段代码

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {    
    int y= (int) ev.getY();    
    if (ev.getAction()==MotionEvent.ACTION_MOVE) {        
        View view=id_bottomview.getChildAt(id_bottomview.getFirstVisiblePosition());        
        if (!isInControl && isTopHidden && (y-lastY)>0 && view!=null && view.getTop()==0) {      
            isInControl=true;            
            ev.setAction(MotionEvent.ACTION_CANCEL);            
            MotionEvent event=ev.obtain(ev);            
            dispatchTouchEvent(ev);            
            event.setAction(MotionEvent.ACTION_DOWN);            
            return dispatchTouchEvent(event);        
        }    
    }    
    return super.dispatchTouchEvent(ev);
}

这段代码的目的是,当我们下拉滑动到蓝色区域临界点的时候,直接将当前的move事件终止,转成Cancel事件并且发出一个Down事件重新玩。这边有一个标志位isInControl很重要,如果没有这个标志位,我们每次在下拉到临界点的时候,都是重新走这个Down事件,这样永远也走不到move事件里面去了,所以这里我们只能执行一次dispatchTouchEvent里面的判断

看完了下拉过程,我们再来看看上拉,上拉的代码是在TouchEvent的move里面的

case MotionEvent.ACTION_MOVE:    
    scrollBy(0, lastY-y);    
    if (getScrollY()==mTopViewHeight && (lastY-y)>0) {        
        event.setAction(MotionEvent.ACTION_DOWN);        
        dispatchTouchEvent(event);        
        isInControl=false;    
    }    
    lastY=y;    
    break;

其实道理是一样的,将事件转化成down事件重新分发。有没有想过为什么这边不需要Cancel?因为任何一次完整的事件流都是上面DispatchTouchEvent说的算,至于你onTouchEvent里面是什么action,依然是DispatchTouchEvent来决定

最终效果
上一篇下一篇

猜你喜欢

热点阅读