package com.sothree.slidinguppanel;
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 and RecyclerView, but the library users can override it to add support
* for other views.
*/
public class 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
*
* @param scrollableView the scrollable view
* @param isSlidingUp whether or not the panel is sliding up or 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);
//If the scrollable view is a NestedScrollBlocker, and its indicating that we're not allowed to move,
//return a value > 0
if (rv instanceof NestedScrollBlocker) {
if (!((NestedScrollBlocker) rv).getBlockScroll()) {
return 1;
}
}
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;
}
}
}