仿网易图集详情页

来源:互联网 发布:知否 顾廷烨 死 番外 编辑:程序博客网 时间:2024/05/21 09:14

       近期我们可爱的产品提了一个需求,要向大厂看齐。仿照某易新闻客户端,在浏览图集的时候,希望底下的文字可以滚动。怎么样个滚动法呢,效果如下:

                                                

       当文本过长时,可以和标题一起向上滚动。当滚动到一个最大高度时,如果文本还未完全显示,可以继续滚动。需求看似很简单,一开始的思路是Scrollview进行嵌套,一番研究后发现一个问题。Scrollview的TouchEvent事件中判断如果是拖动操作会一直拦截,导致即使外层的Scrollview滑到顶部了,里层的Scrollview也接受不到触摸事件。

@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {    /*     * This method JUST determines whether we want to intercept the motion.     * If we return true, onMotionEvent will be called and we do the actual     * scrolling there.     */    /*    * Shortcut the most recurring case: the user is in the dragging    * state and he is moving his finger.  We want to intercept this    * motion.    */    final int action = ev.getAction();   if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {        return true;    }    /*     * Don't try to intercept touch if we can't scroll anyway.     */    if (getScrollY() == 0 && !canScrollVertically(1)) {        return false;    }
    ........
}
    截取了其中的一段源码,mIsBeingDragged变量一旦置为true,ScrollView会直接拦截触摸事件并处理,直到执行完ACTION_UP。这就很尴尬了啊,我必须先滑动父Scrollview到顶部,然后松开手指,再滑动子Scrollview才能滚动文本。类似如下的效果:
                                               

       不是如丝般顺滑,怎么能接受呢。如果想继续优化,必须对触摸事件的分发和拦截重新复写,感觉是个无底洞,果断放弃。后来无意间看到一个ObservableScrollView的Demo,受到了启发。

                                               

        和我的需求很吻合啊,如获至宝,研读一番发现,如来它只有一个Scrollview,标题根据滚动的距离来tranlation,很鸡贼啊!本着拿来主义的精神,立即对其一番改造。在图集的ViewPage上加一层头部透明的Scrollview,title的高度进行计算设置,不就OK了么!但有一个问题需要注意,即ScrollView透明的头部用户看不见,但是响应滑动事件,同时拦截了下面ViewPage的翻页操作,这显然是个bug。我们只需在上面ScrollView中的dispatchTouchEvent做下处理就行了。

@Override    public boolean dispatchTouchEvent(MotionEvent ev) {        boolean dispatch = super.dispatchTouchEvent(ev);        if (mIgnoreTouchRect != null) {            Rect curTouchRect = new Rect(mIgnoreTouchRect.left, mIgnoreTouchRect.top, mIgnoreTouchRect.right, mIgnoreTouchRect.bottom - mScrollY > 0 ? mIgnoreTouchRect.bottom - mScrollY : 0);            if (curTouchRect.contains((int)ev.getX(), (int)ev.getY())) {                return false;            } else {                return dispatch;            }        } else {            return dispatch;        }    }
    这里的mIgnoreTouchRect是初始化时设置的,即我们不拦截触摸操作的区域,之所以又减了个mScrollY的高度,是考虑到ScrollView滚动后,非触摸操作区域的变化。好了,到这所有的问题都完美解决了。
                           
    怎么样?perfect!希望对有相同需求的同学有一点帮助,需要源码的可以给我留言。

0 0
原创粉丝点击