Skip to content

[RTM] Refactored ScrollableViewHelper to interface #635

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 14 additions & 47 deletions library/src/com/sothree/slidinguppanel/ScrollableViewHelper.java
Original file line number Diff line number Diff line change
@@ -1,63 +1,30 @@
package com.sothree.slidinguppanel;

import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ListView;
import android.widget.ScrollView;

/**
* Helper class for determining the current scroll positions for scrollable views. Currently works
* for ListView, ScrollView & RecyclerView, but the library users can override it to add support
* for other views.
* Helper class for determining the scroll capability for scrollable views.
*/
public class ScrollableViewHelper {
public interface ScrollableViewHelper {
/**
* Returns the current scroll position of the scrollable view. If this method returns zero or
* less, it means at the scrollable view is in a position such as the panel should handle
* scrolling. If the method returns anything above zero, then the panel will let the scrollable
* view handle the scrolling
* If this method returns zero false or it means at the scrollable view is in a position such
* as the panel should handle scrolling. If the method returns anything above zero,
* then the panel will let the scrollable view handle the scrolling
*
* @param scrollableView the scrollable view
* @param isSlidingUp whether or not the panel is sliding up or down
* @param direction negative to check scrolling up, positive to check scrolling down.
* @return the scroll position
*/
public int getScrollableViewScrollPosition(View scrollableView, boolean isSlidingUp) {
if (scrollableView == null) return 0;
if (scrollableView instanceof ScrollView) {
if (isSlidingUp) {
return scrollableView.getScrollY();
} else {
ScrollView sv = ((ScrollView) scrollableView);
View child = sv.getChildAt(0);
return (child.getBottom() - (sv.getHeight() + sv.getScrollY()));
}
} else if (scrollableView instanceof ListView && ((ListView) scrollableView).getChildCount() > 0) {
ListView lv = ((ListView) scrollableView);
if (lv.getAdapter() == null) return 0;
if (isSlidingUp) {
View firstChild = lv.getChildAt(0);
// Approximate the scroll position based on the top child and the first visible item
return lv.getFirstVisiblePosition() * firstChild.getHeight() - firstChild.getTop();
} else {
View lastChild = lv.getChildAt(lv.getChildCount() - 1);
// Approximate the scroll position based on the bottom child and the last visible item
return (lv.getAdapter().getCount() - lv.getLastVisiblePosition() - 1) * lastChild.getHeight() + lastChild.getBottom() - lv.getBottom();
}
} else if (scrollableView instanceof RecyclerView && ((RecyclerView) scrollableView).getChildCount() > 0) {
RecyclerView rv = ((RecyclerView) scrollableView);
RecyclerView.LayoutManager lm = rv.getLayoutManager();
if (rv.getAdapter() == null) return 0;
if (isSlidingUp) {
View firstChild = rv.getChildAt(0);
// Approximate the scroll position based on the top child and the first visible item
return rv.getChildLayoutPosition(firstChild) * lm.getDecoratedMeasuredHeight(firstChild) - lm.getDecoratedTop(firstChild);
} else {
View lastChild = rv.getChildAt(rv.getChildCount() - 1);
// Approximate the scroll position based on the bottom child and the last visible item
return (rv.getAdapter().getItemCount() - 1) * lm.getDecoratedMeasuredHeight(lastChild) + lm.getDecoratedBottom(lastChild) - rv.getBottom();
}
} else {
return 0;
public boolean canScrollVertically(View scrollableView, int direction);

static final ScrollableViewHelper DEFAULT = new ScrollableViewHelper() {
@Override
public boolean canScrollVertically(View scrollableView, int direction) {
return ViewCompat.canScrollVertically(scrollableView, direction);
}
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public class SlidingUpPanelLayout extends ViewGroup {
*/
private View mScrollableView;
private int mScrollableViewResId;
private ScrollableViewHelper mScrollableViewHelper = new ScrollableViewHelper();
private ScrollableViewHelper mScrollableViewHelper = ScrollableViewHelper.DEFAULT;

/**
* The child view that can slide, if any.
Expand Down Expand Up @@ -984,7 +984,7 @@ public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
if (dy * (mIsSlidingUp ? 1 : -1) > 0) { // Collapsing
// Is the child less than fully scrolled?
// Then let the child handle it.
if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mIsSlidingUp) > 0) {
if (mScrollableViewHelper.canScrollVertically(mScrollableView, mIsSlidingUp ? -1 : 1)) {
mIsScrollableViewHandlingTouch = true;
return super.dispatchTouchEvent(ev);
}
Expand Down