diff --git a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java index 0ccc6cf..53f5c80 100644 --- a/src/com/github/ysamlan/horizontalpager/HorizontalPager.java +++ b/src/com/github/ysamlan/horizontalpager/HorizontalPager.java @@ -138,6 +138,15 @@ private void init() { mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); } + public int getVisibleCount () { + int count = 0; + for (int i = 0; i < super.getChildCount(); i++) + if (getChildAt(i).getVisibility() != View.GONE) + count++; + + return count; + } + @Override protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -175,7 +184,7 @@ else if (width != mLastSeenLayoutWidth) { // Width has changed .getDefaultDisplay(); int displayWidth = display.getWidth(); - mNextScreen = Math.max(0, Math.min(getCurrentScreen(), getChildCount() - 1)); + mNextScreen = Math.max(0, Math.min(getCurrentScreen(), getVisibleCount() - 1)); final int newX = mNextScreen * displayWidth; final int delta = newX - getScrollX(); @@ -351,7 +360,7 @@ public boolean onTouchEvent(final MotionEvent ev) { // Fling hard enough to move left snapToScreen(mCurrentScreen - 1); } else if (velocityX < -mDensityAdjustedSnapVelocity - && mCurrentScreen < getChildCount() - 1) { + && mCurrentScreen < getVisibleCount() - 1) { // Fling hard enough to move right snapToScreen(mCurrentScreen + 1); } else { @@ -382,8 +391,14 @@ public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); + + // Notify observer about screen change + if (mOnScreenSwitchListener != null) { + int switchingScreen = Math.max(0, Math.min(mNextScreen, getVisibleCount() - 1)); + mOnScreenSwitchListener.onScreenSelected(switchingScreen); + } } else if (mNextScreen != INVALID_SCREEN) { - mCurrentScreen = Math.max(0, Math.min(mNextScreen, getChildCount() - 1)); + mCurrentScreen = Math.max(0, Math.min(mNextScreen, getVisibleCount() - 1)); // Notify observer about screen change if (mOnScreenSwitchListener != null) { @@ -410,7 +425,7 @@ public int getCurrentScreen() { * @param animate True to smoothly scroll to the screen, false to snap instantly */ public void setCurrentScreen(final int currentScreen, final boolean animate) { - mCurrentScreen = Math.max(0, Math.min(currentScreen, getChildCount() - 1)); + mCurrentScreen = Math.max(0, Math.min(currentScreen, getVisibleCount() - 1)); if (animate) { snapToScreen(currentScreen, ANIMATION_SCREEN_SET_DURATION_MILLIS); } else { @@ -443,7 +458,7 @@ private void snapToDestination() { && ((screenWidth / FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE) < -deltaX)) { whichScreen--; // Check if they want to go to the next screen - } else if ((deltaX > 0) && (mCurrentScreen + 1 != getChildCount()) + } else if ((deltaX > 0) && (mCurrentScreen + 1 != getVisibleCount()) && ((screenWidth / FRACTION_OF_SCREEN_WIDTH_FOR_SWIPE) < deltaX)) { whichScreen++; } @@ -475,7 +490,7 @@ private void snapToScreen(final int whichScreen, final int duration) { * RadioGroup used as "tabbed" controls. Also, make the animation take a percentage of our * normal animation time, depending how far they've already scrolled. */ - mNextScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); + mNextScreen = Math.max(0, Math.min(whichScreen, getVisibleCount() - 1)); final int newX = mNextScreen * getWidth(); final int delta = newX - getScrollX(); @@ -494,6 +509,13 @@ private void snapToScreen(final int whichScreen, final int duration) { * Listener for the event that the HorizontalPager switches to a new view. */ public static interface OnScreenSwitchListener { + /** + * Notifies listeners about the new screen. Runs before the animation completed. + * + * @param screen The new screen index. + */ + void onScreenSelected(int screen); + /** * Notifies listeners about the new screen. Runs after the animation completed. *