20
20
import android .content .res .TypedArray ;
21
21
import android .os .Build ;
22
22
import android .util .AttributeSet ;
23
+ import android .util .Log ;
23
24
import android .view .View ;
24
25
25
26
import androidx .annotation .RequiresApi ;
33
34
34
35
public class Carousel extends MotionHelper {
35
36
private static final boolean DEBUG = false ;
37
+ private static final String TAG = "Carousel" ;
36
38
private Adapter mAdapter = null ;
37
39
private ArrayList <View > mList = new ArrayList <>();
38
40
private int mPreviousIndex = 0 ;
39
41
private int mIndex = 0 ;
40
42
private MotionLayout mMotionLayout ;
41
43
private int firstViewReference = -1 ;
42
- private int lastViewReference = -1 ;
43
44
44
45
private int backwardTransition = -1 ;
45
46
private int forwardTransition = -1 ;
46
- private int forwardStartTransition = -1 ; // optional
47
- private int forwardEndTransition = -1 ; // optional
48
- private int forwardMinEndTransition = -1 ; // optional
49
- private int defaultTransition = -1 ; // optional
50
- private int minEndThreshold = -1 ;
51
47
private int previousState = -1 ;
52
48
private int nextState = -1 ;
53
49
private float dampening = 0.9f ;
54
50
private int startIndex = 0 ;
55
- private int endIndex = 0 ;
51
+ private int emptyViewBehavior = INVISIBLE ;
56
52
57
53
public static final int TOUCH_UP_IMMEDIATE_STOP = 1 ;
58
54
public static final int TOUCH_UP_CARRY_ON = 2 ;
@@ -63,8 +59,7 @@ public class Carousel extends MotionHelper {
63
59
public interface Adapter {
64
60
int count ();
65
61
void populate (View view , int index );
66
-
67
- void newItem (int mIndex );
62
+ void onNewItem (int mIndex );
68
63
}
69
64
70
65
public Carousel (Context context ) {
@@ -89,22 +84,12 @@ private void init(Context context, AttributeSet attrs) {
89
84
int attr = a .getIndex (i );
90
85
if (attr == R .styleable .Carousel_carousel_firstView ) {
91
86
firstViewReference = a .getResourceId (attr , firstViewReference );
92
- } else if (attr == R .styleable .Carousel_carousel_lastView ) {
93
- lastViewReference = a .getResourceId (attr , lastViewReference );
94
87
} else if (attr == R .styleable .Carousel_carousel_backwardTransition ) {
95
88
backwardTransition = a .getResourceId (attr , backwardTransition );
96
89
} else if (attr == R .styleable .Carousel_carousel_forwardTransition ) {
97
90
forwardTransition = a .getResourceId (attr , forwardTransition );
98
- } else if (attr == R .styleable .Carousel_carousel_forwardStartTransition ) {
99
- forwardStartTransition = a .getResourceId (attr , forwardStartTransition );
100
- } else if (attr == R .styleable .Carousel_carousel_forwardEndTransition ) {
101
- forwardEndTransition = a .getResourceId (attr , forwardEndTransition );
102
- } else if (attr == R .styleable .Carousel_carousel_forwardMinEndTransition ) {
103
- forwardMinEndTransition = a .getResourceId (attr , forwardMinEndTransition );
104
- } else if (attr == R .styleable .Carousel_carousel_defaultTransition ) {
105
- defaultTransition = a .getResourceId (attr , defaultTransition );
106
- } else if (attr == R .styleable .Carousel_carousel_minEndThreshold ) {
107
- minEndThreshold = a .getInteger (attr , minEndThreshold );
91
+ } else if (attr == R .styleable .Carousel_carousel_emptyViewsBehavior ) {
92
+ emptyViewBehavior = a .getInt (attr , emptyViewBehavior );
108
93
} else if (attr == R .styleable .Carousel_carousel_previousState ) {
109
94
previousState = a .getResourceId (attr , previousState );
110
95
} else if (attr == R .styleable .Carousel_carousel_nextState ) {
@@ -128,7 +113,7 @@ public void refresh() {
128
113
for (int i = 0 ; i < count ; i ++) {
129
114
View view = mList .get (i );
130
115
if (mAdapter .count () == 0 ) {
131
- updateViewVisibility (view , INVISIBLE );
116
+ updateViewVisibility (view , emptyViewBehavior );
132
117
} else {
133
118
updateViewVisibility (view , VISIBLE );
134
119
}
@@ -142,28 +127,43 @@ public void onTransitionChange(MotionLayout motionLayout, int startId, int endId
142
127
if (DEBUG ) {
143
128
System .out .println ("onTransitionChange from " + startId + " to " + endId + " progress " + progress );
144
129
}
130
+ mLastStartId = startId ;
145
131
}
146
132
133
+ int mLastStartId = -1 ;
134
+
147
135
@ Override
148
136
public void onTransitionCompleted (MotionLayout motionLayout , int currentId ) {
137
+ System .out .println ("on transition completed" );
149
138
mPreviousIndex = mIndex ;
150
139
if (currentId == nextState ) {
151
140
mIndex ++;
141
+ System .out .println ("increment index..." );
152
142
} else if (currentId == previousState ) {
153
143
mIndex --;
144
+ System .out .println ("decrement index..." );
154
145
}
155
146
if (mIndex >= mAdapter .count ()) {
156
147
mIndex = mAdapter .count () - 1 ;
148
+ System .out .println ("index capped... " + mIndex );
157
149
}
158
150
if (mIndex < 0 ) {
159
151
mIndex = 0 ;
152
+ System .out .println ("index zeroed... " );
160
153
}
161
154
162
155
if (mPreviousIndex != mIndex ) {
163
156
mMotionLayout .post (mUpdateRunnable );
164
157
}
165
158
}
166
159
160
+ private void enableAllTransitions (boolean enable ) {
161
+ ArrayList <MotionScene .Transition > transitions = mMotionLayout .getDefinedTransitions ();
162
+ for (MotionScene .Transition transition : transitions ) {
163
+ transition .setEnable (enable );
164
+ }
165
+ }
166
+
167
167
private boolean enableTransition (int transitionID , boolean enable ) {
168
168
if (transitionID == -1 ) {
169
169
return false ;
@@ -187,7 +187,7 @@ private boolean enableTransition(int transitionID, boolean enable) {
187
187
public void run () {
188
188
mMotionLayout .setProgress (0 );
189
189
updateItems ();
190
- mAdapter .newItem (mIndex );
190
+ mAdapter .onNewItem (mIndex );
191
191
float velocity = mMotionLayout .getVelocity ();
192
192
if (touchUpMode == TOUCH_UP_CARRY_ON && velocity > velocityThreshold && mIndex < mAdapter .count () - 1 ) {
193
193
final float v = velocity * dampening ;
@@ -225,9 +225,6 @@ protected void onAttachedToWindow() {
225
225
if (firstViewReference == id ) {
226
226
startIndex = i ;
227
227
}
228
- if (lastViewReference == id ) {
229
- endIndex = i ;
230
- }
231
228
mList .add (view );
232
229
}
233
230
mMotionLayout = container ;
@@ -272,36 +269,15 @@ private boolean updateViewVisibility(int constraintSetId, View view, int visibil
272
269
if (constraint == null ) {
273
270
return false ;
274
271
}
275
- if (constraint .propertySet .visibility == visibility ) {
276
- return false ;
277
- }
278
- constraint .propertySet .visibility = visibility ;
272
+ constraint .propertySet .mVisibilityMode = ConstraintSet .VISIBILITY_MODE_IGNORE ;
273
+ // if (constraint.propertySet.visibility == visibility) {
274
+ // return false;
275
+ // }
276
+ // constraint.propertySet.visibility = visibility;
279
277
view .setVisibility (visibility );
280
278
return true ;
281
279
}
282
280
283
- private void updateItemsVisibility () {
284
- if (mAdapter == null ) {
285
- return ;
286
- }
287
- if (mMotionLayout == null ) {
288
- return ;
289
- }
290
- final int count = mList .size ();
291
- for (int i = 0 ; i < count ; i ++) {
292
- // mIndex should map to i == startIndex
293
- View view = mList .get (i );
294
- int index = mIndex + i - startIndex ;
295
- if (index < 0 ) {
296
- updateViewVisibility (view , INVISIBLE );
297
- } else if (index >= mAdapter .count ()) {
298
- updateViewVisibility (view , INVISIBLE );
299
- } else {
300
- updateViewVisibility (view , VISIBLE );
301
- }
302
- }
303
- }
304
-
305
281
private void updateItems () {
306
282
if (mAdapter == null ) {
307
283
return ;
@@ -312,96 +288,38 @@ private void updateItems() {
312
288
if (DEBUG ) {
313
289
System .out .println ("Update items, index: " + mIndex );
314
290
}
315
- final int count = mList .size ();
316
- boolean needsToRebuild = false ;
317
- for (int i = 0 ; i < count ; i ++) {
291
+ final int viewCount = mList .size ();
292
+ for (int i = 0 ; i < viewCount ; i ++) {
318
293
// mIndex should map to i == startIndex
319
294
View view = mList .get (i );
320
295
int index = mIndex + i - startIndex ;
321
296
if (index < 0 ) {
322
- if (forwardEndTransition == -1 ) {
323
- // no custom start transition, so let's make those views invisible
324
- needsToRebuild |= updateViewVisibility (view , INVISIBLE );
325
- }
297
+ updateViewVisibility (view , emptyViewBehavior );
326
298
} else if (index >= mAdapter .count ()) {
327
- if (forwardEndTransition == -1 ) {
328
- // no custom end transition, so let's make those views invisible
329
- needsToRebuild |= updateViewVisibility (view , INVISIBLE );
330
- }
299
+ updateViewVisibility (view , emptyViewBehavior );
331
300
} else {
332
- if (forwardStartTransition == -1 || forwardEndTransition == -1 ) {
333
- // if we don't have a start/end transitions, we might have modified the
334
- // visibility of the views, so let's make sure they are visible
335
- needsToRebuild |= updateViewVisibility (view , VISIBLE );
336
- }
301
+ updateViewVisibility (view , VISIBLE );
337
302
mAdapter .populate (view , index );
338
303
}
339
304
}
340
305
341
- if (backwardTransition != -1 && forwardTransition != -1 ) {
342
- if (mAdapter .count () > 1 ) {
343
- if (mIndex == 0 ) {
344
- needsToRebuild |= enableTransition (backwardTransition , false );
345
- if (forwardStartTransition != -1 ) {
346
- needsToRebuild |= enableTransition (forwardTransition , false );
347
- needsToRebuild |= enableTransition (forwardStartTransition , true );
348
- mMotionLayout .setTransition (forwardStartTransition );
349
- } else {
350
- mMotionLayout .setTransition (forwardTransition );
351
- }
352
- } else {
353
- needsToRebuild |= enableTransition (backwardTransition , true );
354
- }
355
- }
356
-
357
- if (mAdapter .count () == 0 ) {
358
- for (int i = 0 ; i < count ; i ++) {
359
- // mIndex should map to i == startIndex
360
- View view = mList .get (i );
361
- // needsToRebuild |= updateViewVisibility(view, INVISIBLE);
362
- }
363
- } else if (mAdapter .count () == 1 && defaultTransition != -1 ) {
364
- enableTransition (defaultTransition , true );
365
- mMotionLayout .setTransition (defaultTransition );
366
- mMotionLayout .setProgress (0 );
367
- } else if (mAdapter .count () > 1 ) {
368
- if (mIndex == mAdapter .count () - 1 ) {
369
- needsToRebuild |= enableTransition (forwardTransition , false );
370
- if (forwardEndTransition != -1 ) {
371
- needsToRebuild |= enableTransition (forwardEndTransition , false );
372
- }
373
- mMotionLayout .setTransition (backwardTransition );
374
- } else {
375
- int lastVisibleIndex = Math .max (0 , mAdapter .count () - (mList .size () - endIndex ) - 1 );
376
- if (DEBUG ) {
377
- System .out .println ("### index " + mIndex + " endIndex: " + endIndex + " last index is " + lastVisibleIndex + " count " + mAdapter .count ());
378
- }
379
- if (mIndex == lastVisibleIndex && forwardEndTransition != -1 ) {
380
- if (mIndex == 0 ) {
381
- if (forwardMinEndTransition != -1 && mAdapter .count () < minEndThreshold ) {
382
- needsToRebuild |= enableTransition (forwardTransition , false );
383
- needsToRebuild |= enableTransition (forwardStartTransition , false );
384
- needsToRebuild |= enableTransition (forwardMinEndTransition , true );
385
- mMotionLayout .setTransition (forwardMinEndTransition );
386
- } else {
387
- needsToRebuild |= enableTransition (forwardTransition , false );
388
- needsToRebuild |= enableTransition (forwardStartTransition , true );
389
- mMotionLayout .setTransition (forwardStartTransition );
390
- }
391
- } else {
392
- needsToRebuild |= enableTransition (forwardTransition , false );
393
- needsToRebuild |= enableTransition (forwardEndTransition , true );
394
- mMotionLayout .setTransition (forwardEndTransition );
395
- }
396
- } else {
397
- needsToRebuild |= enableTransition (forwardTransition , true );
398
- }
399
- }
400
- }
306
+ if (backwardTransition == -1 || forwardTransition == -1 ) {
307
+ Log .w (TAG , "No backward or forward transitions defined for Carousel!" );
308
+ return ;
401
309
}
402
310
403
- if (needsToRebuild ) {
404
- mMotionLayout .rebuildScene ();
311
+ final int count = mAdapter .count ();
312
+ if (mIndex == 0 ) {
313
+ enableTransition (backwardTransition , false );
314
+ } else {
315
+ enableTransition (backwardTransition , true );
316
+ mMotionLayout .setTransition (backwardTransition );
317
+ }
318
+ if (mIndex == count - 1 ) {
319
+ enableTransition (forwardTransition , false );
320
+ } else {
321
+ enableTransition (forwardTransition , true );
322
+ mMotionLayout .setTransition (forwardTransition );
405
323
}
406
324
}
407
325
0 commit comments