ScrollView Inside ScrollView

后端 未结 13 747
隐瞒了意图╮
隐瞒了意图╮ 2020-11-22 15:40

I Know people from Google have asked us not to put Scrollable view inside another Scrollable view but is there any official statement from them directing us not to do so?

13条回答
  •  逝去的感伤
    2020-11-22 16:10

    Here is a possible solution. When reached the end of a child ScrollView it passes the control to the parent ScrollView to scroll. It works with ScrollView and ListView inside a ScrollView.

    Step 1 - set the parent OnTouchListener

    parentScroll.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(false);
            return false;
        }
    });
    

    Step 2 - set the childrens OnTouchListener (ScrollView or ListView)

    aChildScrollView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event)
        {
            v.getParent().requestDisallowInterceptTouchEvent(shouldRequestDisallowIntercept((ViewGroup) v, event));
            return false;
        }
    });
    aListView.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            v.getParent().requestDisallowInterceptTouchEvent(shouldRequestDisallowIntercept((ViewGroup) v, event));
            return false;
        }
    });
    

    Step 3 - here are the required magic methods for the correct functionality

    protected boolean shouldRequestDisallowIntercept(ViewGroup scrollView, MotionEvent event) {
        boolean disallowIntercept = true;
        float yOffset = getYOffset(event);
    
        if (scrollView instanceof ListView) {
            ListView listView = (ListView) scrollView;
            if (yOffset < 0 && listView.getFirstVisiblePosition() == 0 && listView.getChildAt(0).getTop() >= 0) {
                disallowIntercept = false;
            }
            else if (yOffset > 0 && listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 && listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight()) {
                disallowIntercept = false;
            }
        }
        else {
            float scrollY = scrollView.getScrollY();
            disallowIntercept = !((scrollY == 0 && yOffset < 0) || (scrollView.getHeight() + scrollY == scrollView.getChildAt(0).getHeight() && yOffset >= 0));
    
        }
    
        return disallowIntercept;
    }
    
    protected float getYOffset(MotionEvent ev) {
        final int historySize = ev.getHistorySize();
        final int pointerCount = ev.getPointerCount();
    
        if (historySize > 0 && pointerCount > 0) {
            float lastYOffset = ev.getHistoricalY(pointerCount - 1, historySize - 1);
            float currentYOffset = ev.getY(pointerCount - 1);
    
            float dY = lastYOffset - currentYOffset;
    
            return dY;
        }
    
        return 0;
    }
    

提交回复
热议问题