1
1
package com .yoksnod .parallaxbackgroundviewpager ;
2
2
3
+ import android .support .annotation .Nullable ;
3
4
import android .support .v4 .app .Fragment ;
4
5
import android .support .v4 .app .FragmentPagerAdapter ;
5
6
import android .support .v4 .view .ViewPager ;
6
7
import android .support .v7 .app .AppCompatActivity ;
8
+ import android .util .Log ;
7
9
import android .view .View ;
8
10
import android .widget .ImageView ;
9
11
10
12
import java .util .List ;
11
- import java .util .NoSuchElementException ;
12
13
13
14
public class ParallaxBackgroundPageListener implements ViewPager .OnPageChangeListener {
14
15
16
+ private static final String TAG = "ParallaxListener" ;
15
17
private static final String ANDROID_SWITCHER_TAG_SEGMENT = "android:switcher:" ;
16
18
private static final String SEPARATOR_TAG_SEGMENT = ":" ;
17
19
private static final float POSITION_OFFSET_BASE = 0.5f ;
@@ -48,27 +50,27 @@ private static String makePagerFragmentTag(int index, int pagerId) {
48
50
49
51
@ Override
50
52
public void onPageScrolled (int position , float positionOffset , int positionOffsetPixels ) {
53
+ Log .d (TAG , "onPageScrolled position = " + position + " currentPagePosition = " + currentPagePosition + " shouldCalculateScrollDirection = " + shouldCalculateScrollDirection );
51
54
recalculateScrollDirection (positionOffset , positionOffsetPixels );
52
55
53
56
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 );
57
61
58
- int animatedItemIndex = isScrollToRight ? currentPagePosition : currentPagePosition - 1 ;
59
62
setAlpha (animatedItemIndex , scrollX );
60
63
64
+
61
65
if (isLeftEdge (scrollX )) {
62
66
restoreInitialAlphaValues ();
63
67
}
64
68
}
65
69
66
- private boolean canScrollToLeft (int scrollX ) {
67
- return isLeftEdge (scrollX ) && !isScrollToRight ;
68
- }
69
-
70
70
private void setAlpha (int animatedItemIndex , int scrollX ) {
71
71
View child = findFragmentViewByIndex (animatedItemIndex );
72
+ if (child == null )
73
+ return ;
72
74
ViewPager .LayoutParams lp = (ViewPager .LayoutParams ) child .getLayoutParams ();
73
75
if (lp .isDecor ) {
74
76
return ;
@@ -77,11 +79,12 @@ private void setAlpha(int animatedItemIndex, int scrollX) {
77
79
initCurrentAlpha (transformPos , animatedItemIndex );
78
80
}
79
81
82
+ @ Nullable
80
83
private View findFragmentViewByIndex (int index ) {
81
84
String tag = makePagerFragmentTag (index , pager .getId ());
82
85
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 ;
85
88
86
89
return page .getView ();
87
90
}
@@ -101,10 +104,6 @@ private void initCurrentAlpha(float transformPos, int itemIndex) {
101
104
}
102
105
}
103
106
104
- private boolean isRightEdge (int scrollX ) {
105
- return scrollX == pager .getWidth () * adapter .getCount ();
106
- }
107
-
108
107
109
108
private void restoreInitialAlphaValues () {
110
109
for (int j = items .size () - 1 ; j >= 0 ; j --) {
@@ -130,24 +129,41 @@ public void onPageSelected(int position) {
130
129
if (position == 0 ) {
131
130
onPageScrollStateChanged (ViewPager .SCROLL_STATE_IDLE );
132
131
}
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
+
133
141
}
134
142
135
143
@ Override
136
144
public void onPageScrollStateChanged (int state ) {
137
145
currentPageScrollState = state ;
146
+ Log .d (TAG , "onPageScrollStateChanged state = " + PagerState .values ()[state ] + " currentPagePosition = " + currentPagePosition + " pager current item = " + pager .getCurrentItem ());
147
+
148
+
138
149
if (state == ViewPager .SCROLL_STATE_IDLE ) {
139
150
currentPagePosition = pager .getCurrentItem ();
140
- isScrollToRight = true ;
141
151
}
142
152
143
- boolean isDragScroll = isDragScroll ();
144
- isScrollStarted = isDragScroll ;
145
- if (isDragScroll ) {
153
+ boolean isIdle = isIdleScroll ();
154
+ isScrollStarted = isIdle ;
155
+ if (isIdle ) {
146
156
shouldCalculateScrollDirection = true ;
147
157
}
148
158
}
149
159
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
152
168
}
153
169
}
0 commit comments