-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Fixed two nested scroll issues #509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fixed two scroll issues: 1) if you get the panel in a dragging state …
…by dragging the list down, then re-dock the panel by dragging the list up, release, then drag down on the list, it would cause the panel to intercept when it shouldn't. 2) If you were rapidly scrolling in the list by repeating the dragging motion, the list would stop every second drag because the event was being changed from a move to a down.
- Loading branch information
commit bc24980fd0972774b254b5d689cf72167606a6f5
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,10 +11,10 @@ | |
| import android.os.Build; | ||
| import android.os.Parcel; | ||
| import android.os.Parcelable; | ||
| import android.support.annotation.NonNull; | ||
| import android.support.v4.view.MotionEventCompat; | ||
| import android.support.v4.view.ViewCompat; | ||
| import android.util.AttributeSet; | ||
| import android.util.Log; | ||
| import android.view.Gravity; | ||
| import android.view.MotionEvent; | ||
| import android.view.View; | ||
|
|
@@ -70,8 +70,8 @@ public class SlidingUpPanelLayout extends ViewGroup { | |
| /** | ||
| * Default attributes for layout | ||
| */ | ||
| private static final int[] DEFAULT_ATTRS = new int[] { | ||
| android.R.attr.gravity | ||
| private static final int[] DEFAULT_ATTRS = new int[]{ | ||
| android.R.attr.gravity | ||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -167,6 +167,7 @@ public enum PanelState { | |
| HIDDEN, | ||
| DRAGGING | ||
| } | ||
|
|
||
| private PanelState mSlideState = DEFAULT_SLIDE_STATE; | ||
|
|
||
| /** | ||
|
|
@@ -225,30 +226,36 @@ public enum PanelState { | |
| public interface PanelSlideListener { | ||
| /** | ||
| * Called when a sliding pane's position changes. | ||
| * @param panel The child view that was moved | ||
| * | ||
| * @param panel The child view that was moved | ||
| * @param slideOffset The new offset of this sliding pane within its range, from 0-1 | ||
| */ | ||
| public void onPanelSlide(View panel, float slideOffset); | ||
|
|
||
| /** | ||
| * Called when a sliding panel becomes slid completely collapsed. | ||
| * | ||
| * @param panel The child view that was slid to an collapsed position | ||
| */ | ||
| public void onPanelCollapsed(View panel); | ||
|
|
||
| /** | ||
| * Called when a sliding panel becomes slid completely expanded. | ||
| * | ||
| * @param panel The child view that was slid to a expanded position | ||
| */ | ||
| public void onPanelExpanded(View panel); | ||
|
|
||
| /** | ||
| * Called when a sliding panel becomes anchored. | ||
| * | ||
| * @param panel The child view that was slid to a anchored position | ||
| */ | ||
| public void onPanelAnchored(View panel); | ||
|
|
||
| /** | ||
| * Called when a sliding panel becomes completely hidden. | ||
| * | ||
| * @param panel The child view that was slid to a hidden position | ||
| */ | ||
| public void onPanelHidden(View panel); | ||
|
|
@@ -262,15 +269,19 @@ public static class SimplePanelSlideListener implements PanelSlideListener { | |
| @Override | ||
| public void onPanelSlide(View panel, float slideOffset) { | ||
| } | ||
|
|
||
| @Override | ||
| public void onPanelCollapsed(View panel) { | ||
| } | ||
|
|
||
| @Override | ||
| public void onPanelExpanded(View panel) { | ||
| } | ||
|
|
||
| @Override | ||
| public void onPanelAnchored(View panel) { | ||
| } | ||
|
|
||
| @Override | ||
| public void onPanelHidden(View panel) { | ||
| } | ||
|
|
@@ -287,7 +298,7 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs) { | |
| public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { | ||
| super(context, attrs, defStyle); | ||
|
|
||
| if(isInEditMode()) { | ||
| if (isInEditMode()) { | ||
| mShadowDrawable = null; | ||
| mDragHelper = null; | ||
| return; | ||
|
|
@@ -344,7 +355,6 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { | |
| } else { | ||
| mShadowDrawable = getResources().getDrawable(R.drawable.below_shadow); | ||
| } | ||
|
|
||
| } else { | ||
| mShadowDrawable = null; | ||
| } | ||
|
|
@@ -401,6 +411,7 @@ public int getCoveredFadeColor() { | |
|
|
||
| /** | ||
| * Set sliding enabled flag | ||
| * | ||
| * @param enabled flag value | ||
| */ | ||
| public void setTouchEnabled(boolean enabled) { | ||
|
|
@@ -433,7 +444,7 @@ public void setPanelHeight(int val) { | |
| } | ||
| } | ||
|
|
||
| protected void smoothToBottom(){ | ||
| protected void smoothToBottom() { | ||
| smoothSlideTo(0, 0); | ||
| } | ||
|
|
||
|
|
@@ -468,7 +479,7 @@ public int getPanelHeight() { | |
| */ | ||
| public int getCurrentParalaxOffset() { | ||
| // Clamp slide offset at zero for parallax computation; | ||
| int offset = (int)(mParallaxOffset * Math.max(mSlideOffset, 0)); | ||
| int offset = (int) (mParallaxOffset * Math.max(mSlideOffset, 0)); | ||
| return mIsSlidingUp ? -offset : offset; | ||
| } | ||
|
|
||
|
|
@@ -502,6 +513,7 @@ public void setMinFlingVelocity(int val) { | |
|
|
||
| /** | ||
| * Sets the panel slide listener | ||
| * | ||
| * @param listener | ||
| */ | ||
| public void setPanelSlideListener(PanelSlideListener listener) { | ||
|
|
@@ -526,7 +538,7 @@ public void setDragView(View dragView) { | |
| @Override | ||
| public void onClick(View v) { | ||
| if (!isEnabled() || !isTouchEnabled()) return; | ||
| if (mSlideState != PanelState.EXPANDED && mSlideState != PanelState.ANCHORED) { | ||
| if (mSlideState != PanelState.EXPANDED && mSlideState != PanelState.ANCHORED) { | ||
| if (mAnchorPoint < 1.0f) { | ||
| setPanelState(PanelState.ANCHORED); | ||
| } else { | ||
|
|
@@ -536,7 +548,8 @@ public void onClick(View v) { | |
| setPanelState(PanelState.COLLAPSED); | ||
| } | ||
| } | ||
| });; | ||
| }); | ||
| ; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -583,6 +596,7 @@ public float getAnchorPoint() { | |
|
|
||
| /** | ||
| * Sets whether or not the panel overlays the content | ||
| * | ||
| * @param overlayed | ||
| */ | ||
| public void setOverlayed(boolean overlayed) { | ||
|
|
@@ -598,6 +612,7 @@ public boolean isOverlayed() { | |
|
|
||
| /** | ||
| * Sets whether or not the main content is clipped to the top of the panel | ||
| * | ||
| * @param overlayed | ||
| */ | ||
| public void setClipPanel(boolean clip) { | ||
|
|
@@ -800,19 +815,19 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
|
|
||
| if (mFirstLayout) { | ||
| switch (mSlideState) { | ||
| case EXPANDED: | ||
| mSlideOffset = 1.0f; | ||
| break; | ||
| case ANCHORED: | ||
| mSlideOffset = mAnchorPoint; | ||
| break; | ||
| case HIDDEN: | ||
| int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); | ||
| mSlideOffset = computeSlideOffset(newTop); | ||
| break; | ||
| default: | ||
| mSlideOffset = 0.f; | ||
| break; | ||
| case EXPANDED: | ||
| mSlideOffset = 1.0f; | ||
| break; | ||
| case ANCHORED: | ||
| mSlideOffset = mAnchorPoint; | ||
| break; | ||
| case HIDDEN: | ||
| int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); | ||
| mSlideOffset = computeSlideOffset(newTop); | ||
| break; | ||
| default: | ||
| mSlideOffset = 0.f; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -886,7 +901,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { | |
| final float ady = Math.abs(y - mInitialMotionY); | ||
| final int dragSlop = mDragHelper.getTouchSlop(); | ||
|
|
||
| if ((ady > dragSlop && adx > ady) || !isViewUnder(mDragView, (int)mInitialMotionX, (int)mInitialMotionY)) { | ||
| if ((ady > dragSlop && adx > ady) || !isViewUnder(mDragView, (int) mInitialMotionX, (int) mInitialMotionY)) { | ||
| mDragHelper.cancel(); | ||
| mIsUnableToDrag = true; | ||
| return false; | ||
|
|
@@ -909,11 +924,10 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { | |
| } | ||
|
|
||
| @Override | ||
| public boolean onTouchEvent(MotionEvent ev) { | ||
| public boolean onTouchEvent(@NonNull MotionEvent ev) { | ||
| if (!isEnabled() || !isTouchEnabled()) { | ||
| return super.onTouchEvent(ev); | ||
| } | ||
| final int action = MotionEventCompat.getActionMasked(ev); | ||
| try { | ||
| mDragHelper.processTouchEvent(ev); | ||
| return true; | ||
|
|
@@ -924,15 +938,14 @@ public boolean onTouchEvent(MotionEvent ev) { | |
| } | ||
|
|
||
| @Override | ||
| public boolean dispatchTouchEvent(MotionEvent ev) { | ||
| public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { | ||
| final int action = MotionEventCompat.getActionMasked(ev); | ||
|
|
||
| if (!isEnabled() || !isTouchEnabled() || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) { | ||
| mDragHelper.cancel(); | ||
| return super.dispatchTouchEvent(ev); | ||
| } | ||
|
|
||
| final float x = ev.getX(); | ||
| final float y = ev.getY(); | ||
|
|
||
| if (action == MotionEvent.ACTION_DOWN) { | ||
|
|
@@ -985,14 +998,18 @@ public boolean dispatchTouchEvent(MotionEvent ev) { | |
| // Was the panel handling the touch previously? | ||
| // Then we need to rejigger things so that the | ||
| // child gets a proper down event. | ||
| if (!mIsScrollableViewHandlingTouch) { | ||
| if (!mIsScrollableViewHandlingTouch && mDragHelper.isDragging()) { | ||
| mDragHelper.cancel(); | ||
| ev.setAction(MotionEvent.ACTION_DOWN); | ||
| } | ||
|
|
||
| mIsScrollableViewHandlingTouch = true; | ||
| return super.dispatchTouchEvent(ev); | ||
| } | ||
| } else if (action == MotionEvent.ACTION_UP && mIsScrollableViewHandlingTouch) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This fixes the accidental intercept |
||
| // If the scrollable view was handling the touch and we receive an up | ||
| // we want to clear any previous dragging state so we don't intercept a touch stream accidentally | ||
| mDragHelper.setDragState(ViewDragHelper.STATE_IDLE); | ||
| } | ||
|
|
||
| // In all other cases, just let the default behavior take over. | ||
|
|
@@ -1017,12 +1034,12 @@ private int getScrollableViewScrollPosition() { | |
| if (mIsSlidingUp) { | ||
| return mScrollableView.getScrollY(); | ||
| } else { | ||
| ScrollView sv = ((ScrollView)mScrollableView); | ||
| ScrollView sv = ((ScrollView) mScrollableView); | ||
| View child = sv.getChildAt(0); | ||
| return (child.getBottom() - (sv.getHeight() + sv.getScrollY())); | ||
| } | ||
| } else if (mScrollableView instanceof ListView && ((ListView)mScrollableView).getChildCount() > 0) { | ||
| ListView lv = ((ListView)mScrollableView); | ||
| } else if (mScrollableView instanceof ListView && ((ListView) mScrollableView).getChildCount() > 0) { | ||
| ListView lv = ((ListView) mScrollableView); | ||
| if (lv.getAdapter() == null) return 0; | ||
| if (mIsSlidingUp) { | ||
| View firstChild = lv.getChildAt(0); | ||
|
|
@@ -1066,6 +1083,7 @@ private float computeSlideOffset(int topPosition) { | |
|
|
||
| /** | ||
| * Returns the current state of the panel as an enum. | ||
| * | ||
| * @return the current panel state | ||
| */ | ||
| public PanelState getPanelState() { | ||
|
|
@@ -1074,6 +1092,7 @@ public PanelState getPanelState() { | |
|
|
||
| /** | ||
| * Change panel state to the given state with | ||
| * | ||
| * @param state - new panel state | ||
| */ | ||
| public void setPanelState(PanelState state) { | ||
|
|
@@ -1135,7 +1154,7 @@ private void onPanelDragged(int newTop) { | |
| dispatchOnPanelSlide(mSlideableView); | ||
| // If the slide offset is negative, and overlay is not on, we need to increase the | ||
| // height of the main content | ||
| LayoutParams lp = (LayoutParams)mMainView.getLayoutParams(); | ||
| LayoutParams lp = (LayoutParams) mMainView.getLayoutParams(); | ||
| int defaultHeight = getHeight() - getPaddingBottom() - getPaddingTop() - mPanelHeight; | ||
|
|
||
| if (mSlideOffset <= 0 && !mOverlayContent) { | ||
|
|
@@ -1190,7 +1209,7 @@ protected boolean drawChild(Canvas canvas, View child, long drawingTime) { | |
| * Smoothly animate mDraggingPane to the target X position within its range. | ||
| * | ||
| * @param slideOffset position to animate to | ||
| * @param velocity initial velocity in case of fling, or 0. | ||
| * @param velocity initial velocity in case of fling, or 0. | ||
| */ | ||
| boolean smoothSlideTo(float slideOffset, int velocity) { | ||
| if (!isEnabled()) { | ||
|
|
@@ -1244,12 +1263,12 @@ public void draw(Canvas c) { | |
| /** | ||
| * Tests scrollability within child views of v given a delta of dx. | ||
| * | ||
| * @param v View to test for horizontal scrollability | ||
| * @param v View to test for horizontal scrollability | ||
| * @param checkV Whether the view v passed should itself be checked for scrollability (true), | ||
| * or just its children (false). | ||
| * @param dx Delta scrolled in pixels | ||
| * @param x X coordinate of the active touch point | ||
| * @param y Y coordinate of the active touch point | ||
| * @param dx Delta scrolled in pixels | ||
| * @param x X coordinate of the active touch point | ||
| * @param y Y coordinate of the active touch point | ||
| * @return true if child views of v can be scrolled by delta of dx. | ||
| */ | ||
| protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { | ||
|
|
@@ -1416,8 +1435,8 @@ public int clampViewPositionVertical(View child, int top, int dy) { | |
| } | ||
|
|
||
| public static class LayoutParams extends ViewGroup.MarginLayoutParams { | ||
| private static final int[] ATTRS = new int[] { | ||
| android.R.attr.layout_weight | ||
| private static final int[] ATTRS = new int[]{ | ||
| android.R.attr.layout_weight | ||
| }; | ||
|
|
||
| public LayoutParams() { | ||
|
|
@@ -1446,7 +1465,6 @@ public LayoutParams(Context c, AttributeSet attrs) { | |
| final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS); | ||
| a.recycle(); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| static class SavedState extends BaseSavedState { | ||
|
|
@@ -1473,15 +1491,15 @@ public void writeToParcel(Parcel out, int flags) { | |
|
|
||
| public static final Parcelable.Creator<SavedState> CREATOR = | ||
| new Parcelable.Creator<SavedState>() { | ||
| @Override | ||
| public SavedState createFromParcel(Parcel in) { | ||
| return new SavedState(in); | ||
| } | ||
| @Override | ||
| public SavedState createFromParcel(Parcel in) { | ||
| return new SavedState(in); | ||
| } | ||
|
|
||
| @Override | ||
| public SavedState[] newArray(int size) { | ||
| return new SavedState[size]; | ||
| } | ||
| }; | ||
| @Override | ||
| public SavedState[] newArray(int size) { | ||
| return new SavedState[size]; | ||
| } | ||
| }; | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fixes the fling halting.