2020import android .content .res .TypedArray ;
2121import android .os .Build ;
2222import android .util .AttributeSet ;
23+ import android .util .Log ;
2324import android .view .View ;
2425
2526import androidx .annotation .RequiresApi ;
3334
3435public class Carousel extends MotionHelper {
3536 private static final boolean DEBUG = false ;
37+ private static final String TAG = "Carousel" ;
3638 private Adapter mAdapter = null ;
3739 private ArrayList <View > mList = new ArrayList <>();
3840 private int mPreviousIndex = 0 ;
3941 private int mIndex = 0 ;
4042 private MotionLayout mMotionLayout ;
4143 private int firstViewReference = -1 ;
42- private int lastViewReference = -1 ;
4344
4445 private int backwardTransition = -1 ;
4546 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 ;
5147 private int previousState = -1 ;
5248 private int nextState = -1 ;
5349 private float dampening = 0.9f ;
5450 private int startIndex = 0 ;
55- private int endIndex = 0 ;
51+ private int emptyViewBehavior = INVISIBLE ;
5652
5753 public static final int TOUCH_UP_IMMEDIATE_STOP = 1 ;
5854 public static final int TOUCH_UP_CARRY_ON = 2 ;
@@ -63,8 +59,7 @@ public class Carousel extends MotionHelper {
6359 public interface Adapter {
6460 int count ();
6561 void populate (View view , int index );
66-
67- void newItem (int mIndex );
62+ void onNewItem (int mIndex );
6863 }
6964
7065 public Carousel (Context context ) {
@@ -89,22 +84,12 @@ private void init(Context context, AttributeSet attrs) {
8984 int attr = a .getIndex (i );
9085 if (attr == R .styleable .Carousel_carousel_firstView ) {
9186 firstViewReference = a .getResourceId (attr , firstViewReference );
92- } else if (attr == R .styleable .Carousel_carousel_lastView ) {
93- lastViewReference = a .getResourceId (attr , lastViewReference );
9487 } else if (attr == R .styleable .Carousel_carousel_backwardTransition ) {
9588 backwardTransition = a .getResourceId (attr , backwardTransition );
9689 } else if (attr == R .styleable .Carousel_carousel_forwardTransition ) {
9790 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 );
10893 } else if (attr == R .styleable .Carousel_carousel_previousState ) {
10994 previousState = a .getResourceId (attr , previousState );
11095 } else if (attr == R .styleable .Carousel_carousel_nextState ) {
@@ -128,7 +113,7 @@ public void refresh() {
128113 for (int i = 0 ; i < count ; i ++) {
129114 View view = mList .get (i );
130115 if (mAdapter .count () == 0 ) {
131- updateViewVisibility (view , INVISIBLE );
116+ updateViewVisibility (view , emptyViewBehavior );
132117 } else {
133118 updateViewVisibility (view , VISIBLE );
134119 }
@@ -142,28 +127,43 @@ public void onTransitionChange(MotionLayout motionLayout, int startId, int endId
142127 if (DEBUG ) {
143128 System .out .println ("onTransitionChange from " + startId + " to " + endId + " progress " + progress );
144129 }
130+ mLastStartId = startId ;
145131 }
146132
133+ int mLastStartId = -1 ;
134+
147135 @ Override
148136 public void onTransitionCompleted (MotionLayout motionLayout , int currentId ) {
137+ System .out .println ("on transition completed" );
149138 mPreviousIndex = mIndex ;
150139 if (currentId == nextState ) {
151140 mIndex ++;
141+ System .out .println ("increment index..." );
152142 } else if (currentId == previousState ) {
153143 mIndex --;
144+ System .out .println ("decrement index..." );
154145 }
155146 if (mIndex >= mAdapter .count ()) {
156147 mIndex = mAdapter .count () - 1 ;
148+ System .out .println ("index capped... " + mIndex );
157149 }
158150 if (mIndex < 0 ) {
159151 mIndex = 0 ;
152+ System .out .println ("index zeroed... " );
160153 }
161154
162155 if (mPreviousIndex != mIndex ) {
163156 mMotionLayout .post (mUpdateRunnable );
164157 }
165158 }
166159
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+
167167 private boolean enableTransition (int transitionID , boolean enable ) {
168168 if (transitionID == -1 ) {
169169 return false ;
@@ -187,7 +187,7 @@ private boolean enableTransition(int transitionID, boolean enable) {
187187 public void run () {
188188 mMotionLayout .setProgress (0 );
189189 updateItems ();
190- mAdapter .newItem (mIndex );
190+ mAdapter .onNewItem (mIndex );
191191 float velocity = mMotionLayout .getVelocity ();
192192 if (touchUpMode == TOUCH_UP_CARRY_ON && velocity > velocityThreshold && mIndex < mAdapter .count () - 1 ) {
193193 final float v = velocity * dampening ;
@@ -225,9 +225,6 @@ protected void onAttachedToWindow() {
225225 if (firstViewReference == id ) {
226226 startIndex = i ;
227227 }
228- if (lastViewReference == id ) {
229- endIndex = i ;
230- }
231228 mList .add (view );
232229 }
233230 mMotionLayout = container ;
@@ -272,36 +269,15 @@ private boolean updateViewVisibility(int constraintSetId, View view, int visibil
272269 if (constraint == null ) {
273270 return false ;
274271 }
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;
279277 view .setVisibility (visibility );
280278 return true ;
281279 }
282280
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-
305281 private void updateItems () {
306282 if (mAdapter == null ) {
307283 return ;
@@ -312,96 +288,38 @@ private void updateItems() {
312288 if (DEBUG ) {
313289 System .out .println ("Update items, index: " + mIndex );
314290 }
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 ++) {
318293 // mIndex should map to i == startIndex
319294 View view = mList .get (i );
320295 int index = mIndex + i - startIndex ;
321296 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 );
326298 } 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 );
331300 } 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 );
337302 mAdapter .populate (view , index );
338303 }
339304 }
340305
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 ;
401309 }
402310
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 );
405323 }
406324 }
407325
0 commit comments