two directional scroll view

前端 未结 9 1263
野的像风
野的像风 2020-12-09 05:03

I would like to have a linearlayout with a header section on top and a webview below. The header will be short and the webview may be longer and wider than the screen.

9条回答
  •  渐次进展
    2020-12-09 05:52

    For a while I've been trying solutions from here, but the one that worked best still had one problem: It ate all events, none were making it through to elements within the scroller.

    So I've got ... yet another answer, in Github and well-commented at least hopefully: https://github.com/Wilm0r/giggity/blob/master/app/src/main/java/net/gaast/giggity/NestedScroller.java

    Like all solutions, it's a nested HorizontalScrollview (outer) + ScrollView (inner), with the outer receiving touch events from Android, and the inner receiving them only internally from the outer view.

    Yet I'm relying on the ScrollViews to decide whether a touch event is interesting and until they accept it, do nothing so touches (i.e. taps to open links/etc) can still make it to child elements.

    (Also the view supports pinch to zoom which I needed.)

    In the outer scroller:

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event)
    {
        if (super.onInterceptTouchEvent(event) || vscroll.onInterceptTouchEventInt(event)) {
            onTouchEvent(event);
            return true;
        }
        return false;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        super.onTouchEvent(event);
        /* Beware: One ugliness of passing on events like this is that normally a ScrollView will
           do transformation of the event coordinates which we're not doing here, mostly because
           things work well enough without doing that.
           For events that we pass through to the child view, transformation *will* happen (because
           we're completely ignoring those and let the (H)ScrollView do the transformation for us).
         */
        vscroll.onTouchEventInt(event);
        return true;
    }
    

    vscroll here is the "InnerScroller", subclassed from ScrollView, with a few changes to event handling: I've done some terrible things to ensure incoming touch events directly from Android are discarded, and instead it will only take them from the outer class - and only then pass those on to the superclass:

        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            /* All touch events should come in via the outer horizontal scroller (using the Int
               functions below). If Android tries to send them here directly, reject. */
            return false;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            /* It will still try to send them anyway if it can't find any interested child elements.
               Reject it harder (but pretend that we took it). */
            return true;
        }
    
        public boolean onInterceptTouchEventInt(MotionEvent event) {
            return super.onInterceptTouchEvent(event);
        }
    
        public boolean onTouchEventInt(MotionEvent event) {
            super.onTouchEvent(event);
        }
    

提交回复
热议问题