11package com .yoksnod .parallaxbackgroundviewpager ;
22
3+ import android .support .annotation .Nullable ;
34import android .support .v4 .app .Fragment ;
45import android .support .v4 .app .FragmentPagerAdapter ;
56import android .support .v4 .view .ViewPager ;
67import android .support .v7 .app .AppCompatActivity ;
8+ import android .util .Log ;
79import android .view .View ;
810import android .widget .ImageView ;
911
1012import java .util .List ;
11- import java .util .NoSuchElementException ;
1213
1314public class ParallaxBackgroundPageListener implements ViewPager .OnPageChangeListener {
1415
16+ private static final String TAG = "ParallaxListener" ;
1517 private static final String ANDROID_SWITCHER_TAG_SEGMENT = "android:switcher:" ;
1618 private static final String SEPARATOR_TAG_SEGMENT = ":" ;
1719 private static final float POSITION_OFFSET_BASE = 0.5f ;
@@ -48,27 +50,27 @@ private static String makePagerFragmentTag(int index, int pagerId) {
4850
4951 @ Override
5052 public void onPageScrolled (int position , float positionOffset , int positionOffsetPixels ) {
53+ Log .d (TAG , "onPageScrolled position = " + position + " currentPagePosition = " + currentPagePosition + " shouldCalculateScrollDirection = " + shouldCalculateScrollDirection );
5154 recalculateScrollDirection (positionOffset , positionOffsetPixels );
5255
5356 int scrollX = pager .getScrollX ();
54- if (canScrollToLeft (scrollX ) || isRightEdge (scrollX )) {
55- return ;
56- }
57+ int animatedItemIndex = isScrollToRight
58+ ? Math .min (currentPagePosition , adapter .getCount () - 1 )
59+ : Math .max (0 , currentPagePosition - 1 );
60+ Log .d (TAG , "onPageScrolled isRight = " + isScrollToRight + " anim index = " + animatedItemIndex );
5761
58- int animatedItemIndex = isScrollToRight ? currentPagePosition : currentPagePosition - 1 ;
5962 setAlpha (animatedItemIndex , scrollX );
6063
64+
6165 if (isLeftEdge (scrollX )) {
6266 restoreInitialAlphaValues ();
6367 }
6468 }
6569
66- private boolean canScrollToLeft (int scrollX ) {
67- return isLeftEdge (scrollX ) && !isScrollToRight ;
68- }
69-
7070 private void setAlpha (int animatedItemIndex , int scrollX ) {
7171 View child = findFragmentViewByIndex (animatedItemIndex );
72+ if (child == null )
73+ return ;
7274 ViewPager .LayoutParams lp = (ViewPager .LayoutParams ) child .getLayoutParams ();
7375 if (lp .isDecor ) {
7476 return ;
@@ -77,11 +79,12 @@ private void setAlpha(int animatedItemIndex, int scrollX) {
7779 initCurrentAlpha (transformPos , animatedItemIndex );
7880 }
7981
82+ @ Nullable
8083 private View findFragmentViewByIndex (int index ) {
8184 String tag = makePagerFragmentTag (index , pager .getId ());
8285 Fragment page = activity .getSupportFragmentManager ().findFragmentByTag (tag );
83- if (page == null )
84- throw new NoSuchElementException ( "no such element for tag : " + tag ) ;
86+ if (page == null || page . getView () == null )
87+ return null ;
8588
8689 return page .getView ();
8790 }
@@ -101,10 +104,6 @@ private void initCurrentAlpha(float transformPos, int itemIndex) {
101104 }
102105 }
103106
104- private boolean isRightEdge (int scrollX ) {
105- return scrollX == pager .getWidth () * adapter .getCount ();
106- }
107-
108107
109108 private void restoreInitialAlphaValues () {
110109 for (int j = items .size () - 1 ; j >= 0 ; j --) {
@@ -130,24 +129,41 @@ public void onPageSelected(int position) {
130129 if (position == 0 ) {
131130 onPageScrollStateChanged (ViewPager .SCROLL_STATE_IDLE );
132131 }
132+
133+ Log .d (TAG , "onPageSelected position = " + position + " currentPagePosition = " + currentPagePosition + " pager current item = " + pager .getCurrentItem ());
134+
135+ if (Math .abs (currentPagePosition - position ) > 1 ) {
136+ currentPagePosition = isScrollToRight
137+ ? Math .max (0 , position - 1 )
138+ : Math .min (position + 1 , adapter .getCount () - 1 );
139+ }
140+
133141 }
134142
135143 @ Override
136144 public void onPageScrollStateChanged (int state ) {
137145 currentPageScrollState = state ;
146+ Log .d (TAG , "onPageScrollStateChanged state = " + PagerState .values ()[state ] + " currentPagePosition = " + currentPagePosition + " pager current item = " + pager .getCurrentItem ());
147+
148+
138149 if (state == ViewPager .SCROLL_STATE_IDLE ) {
139150 currentPagePosition = pager .getCurrentItem ();
140- isScrollToRight = true ;
141151 }
142152
143- boolean isDragScroll = isDragScroll ();
144- isScrollStarted = isDragScroll ;
145- if (isDragScroll ) {
153+ boolean isIdle = isIdleScroll ();
154+ isScrollStarted = isIdle ;
155+ if (isIdle ) {
146156 shouldCalculateScrollDirection = true ;
147157 }
148158 }
149159
150- private boolean isDragScroll () {
151- return !isScrollStarted && currentPageScrollState == ViewPager .SCROLL_STATE_DRAGGING ;
160+ private boolean isIdleScroll () {
161+ return !isScrollStarted && currentPageScrollState == ViewPager .SCROLL_STATE_IDLE ;
162+ }
163+
164+ private enum PagerState {
165+ SCROLL_STATE_IDLE ,
166+ SCROLL_STATE_DRAGGING ,
167+ SCROLL_STATE_SETTLING
152168 }
153169}
0 commit comments