1

I have tried everything to get my ScrollView and SlidingUpPanelLayout to function how Google Maps app handles it. (video example)

This is the only link that seems to actually be working for people, but it is not working for me. https://stackoverflow.com/a/22720204/172336

I've followed it 4 times today and every time my ScrollView scrolls and my SlidingUpPanelLayout does absolutely nothing. (It sits there)

Here is the code I am adding to the code from the SlidingUpPanelLayout as seen on GitHub.

activity_main.xml

<com.bouy76.sportsmantracker.SlidingUpPanelLayout
    android:id="@+id/sliding_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:gravity="bottom"
    app:panelHeight="68dp"
    app:dragView="@+id/drag_view"

    app:scrollView="@+id/scroll_view"> <!-- attrs.xml tag -->

    <!-- MAIN CONTENT -->
    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="top">

        <com.nutiteq.MapView
            android:id="@+id/main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>

    <!-- SLIDING LAYOUT -->
    <RelativeLayout
        android:id="@+id/drag_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true"
        android:focusable="false"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="68dp"
            android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center|start"
            android:paddingLeft="@dimen/activity_vertical_margin"
            android:text="Near Beaver Creek"
            android:textSize="20sp" />

        </LinearLayout>

        <ScrollView

            android:id="@+id/scroll_view" <!-- Match attrs reference -->

            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent"
            android:cacheColorHint="@android:color/white"
            android:divider="@android:color/darker_gray"
            android:dividerHeight="@dimen/divider_height"
            android:layout_marginTop="68dp"
            android:drawSelectorOnTop="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="5000dp"
                android:layout_marginLeft="16dp"
                android:layout_marginRight="16dp"
                android:orientation="vertical"/>

            </LinearLayout>

        </ScrollView>

    </RelativeLayout>

</com.bouy76.sportsmantracker.SlidingUpPanelLayout>

SlidingUpPanelLayout.java

View mScrollView;
int mScrollViewResId = -1;
boolean isChildHandlingTouch = false;
float mPrevMotionX;
float mPrevMotionY;

...

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    if (mDragViewResId != -1) {
        setDragView(findViewById(mDragViewResId));
    }
    if (mScrollViewResId != -1) {
        mScrollView = findViewById(mScrollViewResId);
    }
}

...

private boolean isScrollViewUnder(int x, int y) {
if (mScrollView == null)
    return false;

int[] viewLocation = new int[2];
mScrollView.getLocationOnScreen(viewLocation);
int[] parentLocation = new int[2];
this.getLocationOnScreen(parentLocation);
int screenX = parentLocation[0] + x;
int screenY = parentLocation[1] + y;
return screenX >= viewLocation[0] && 
       screenX < viewLocation[0] + mScrollView.getWidth() && 
       screenY >= viewLocation[1] && 
       screenY < viewLocation[1] + mScrollView.getHeight();
}

...

//Removed the onInterceptTouchEvent Method

...

public boolean onTouchEvent(MotionEvent ev) {
if (!mCanSlide || !mIsSlidingEnabled) {
    return super.onTouchEvent(ev);
}

mDragHelper.processTouchEvent(ev);

final int action = ev.getAction();
boolean wantTouchEvents = false;

switch (action & MotionEventCompat.ACTION_MASK) {
    case MotionEvent.ACTION_UP: {
        final float x = ev.getX();
        final float y = ev.getY();
        final float dx = x - mInitialMotionX;
        final float dy = y - mInitialMotionY;
        final int slop = mDragHelper.getTouchSlop();
        View dragView = mDragView != null ? mDragView : mSlideableView;

        if (dx * dx + dy * dy < slop * slop && 
            isDragViewUnder((int) x, (int) y) &&
            !isScrollViewUnder((int) x, (int) y)) {
            dragView.playSoundEffect(SoundEffectConstants.CLICK);
            if (!isExpanded() && !isAnchored()) {
                expandPane(mAnchorPoint);
            } else {
                collapsePane();
            }
            break;
        }
        break;
    }
}
    return wantTouchEvents;
}

...

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mScrollView == null)
    return super.dispatchTouchEvent(ev);

final int action = MotionEventCompat.getActionMasked(ev);

final float x = ev.getX();
final float y = ev.getY();

if (action == MotionEvent.ACTION_DOWN) {
    mDragHelper.shouldInterceptTouchEvent(ev);

    mInitialMotionX = mPrevMotionX = x;
    mInitialMotionY = mPrevMotionY = y;

    isChildHandlingTouch = false;
} else if (action == MotionEvent.ACTION_MOVE) {
    float dx = x - mPrevMotionX;
    float dy = y - mPrevMotionY;
    mPrevMotionX = x;
    mPrevMotionY = y;

    if (!isScrollViewUnder((int) x, (int) y))
        return this.onTouchEvent(ev);

    if (dy > 0) { // DOWN
        // Is the child less than fully scrolled?
        // Then let the child handle it.
        if (mScrollView.getScrollY() > 0) {
            isChildHandlingTouch = true;
            return super.dispatchTouchEvent(ev);
        }

        if (isChildHandlingTouch) {
            // Send an 'UP' event to the child.
            MotionEvent up = MotionEvent.obtain(ev);
            up.setAction(MotionEvent.ACTION_UP);
            super.dispatchTouchEvent(up);
            up.recycle();

            ev.setAction(MotionEvent.ACTION_DOWN);
        }

        isChildHandlingTouch = false;
        return this.onTouchEvent(ev);
    } else if (dy < 0) {
        if (mSlideOffset > 0.0f) {
            isChildHandlingTouch = false;
            return this.onTouchEvent(ev);
        }

        if (!isChildHandlingTouch) {
            mDragHelper.cancel();
            ev.setAction(MotionEvent.ACTION_DOWN);
        }

        isChildHandlingTouch = true;
        return super.dispatchTouchEvent(ev);
    }
} else if ((action == MotionEvent.ACTION_CANCEL) || 
           (action == MotionEvent.ACTION_UP)) {
    if (!isChildHandlingTouch) {
        final float dx = x - mInitialMotionX;
        final float dy = y - mInitialMotionY;
        final int slop = mDragHelper.getTouchSlop();

        if ((mIsUsingDragViewTouchEvents) && 
            (dx * dx + dy * dy < slop * slop))
            return super.dispatchTouchEvent(ev);

        return this.onTouchEvent(ev);
        }
    }

    return super.dispatchTouchEvent(ev);
}

Again check this for where I'm pulling code. https://stackoverflow.com/a/22720204/172336

Thanks

Community
  • 1
  • 1
Michael
  • 9,639
  • 3
  • 64
  • 69

0 Answers0