1616import java .util .ArrayList ;
1717import java .util .List ;
1818
19+ /**
20+ * This class acts as an adapter for the {@link CardStackLayout} view. This adapter is intentionally
21+ * made an abstract class with following abstract methods -
22+ * <p/>
23+ * <p/>
24+ * {@link #getCount()} - Decides the number of views present in the view
25+ * <p/>
26+ * {@link #createView(int, ViewGroup)} - Creates the view for all positions in range [0, {@link #getCount()})
27+ * <p/>
28+ * Contains the logic for touch events in {@link #onTouch(View, MotionEvent)}
29+ */
1930public abstract class CardStackAdapter implements View .OnTouchListener , View .OnClickListener {
2031
2132
2233 public static final int ANIM_DURATION = 600 ;
2334 public static final int DECELERATION_FACTOR = 2 ;
2435
36+ public static final int INVALID_CARD_POSITION = -1 ;
37+
2538 // Settings for the adapter from layout
2639 private float mCardGapBottom ;
2740 private float mCardGap ;
@@ -43,25 +56,39 @@ public abstract class CardStackAdapter implements View.OnTouchListener, View.OnC
4356 private float mTouchFirstY = -1 ;
4457 private float mTouchPrevY = -1 ;
4558 private float mTouchDistance = 0 ;
46- private int mSelectedCardPosition = - 1 ;
59+ private int mSelectedCardPosition = INVALID_CARD_POSITION ;
4760 private float scaleFactorForElasticEffect ;
4861 private int mParentPaddingTop = 0 ;
4962 private int mCardPaddingInternal = 0 ;
5063
51- public View getCardView (int position ) {
52- if (mCardViews == null ) return null ;
53-
54- return mCardViews [position ];
55- }
56-
64+ /**
65+ * Defines and initializes the view to be shown in the {@link CardStackLayout}
66+ * Provides two parameters to the sub-class namely -
67+ *
68+ * @param position
69+ * @param container
70+ *
71+ * @return View corresponding to the position and parent container
72+ */
5773 public abstract View createView (int position , ViewGroup container );
5874
75+ /**
76+ * Defines the number of cards that are present in the {@link CardStackLayout}
77+ *
78+ * @return cardCount - Number of views in the related {@link CardStackLayout}
79+ */
5980 public abstract int getCount ();
6081
61- public void setScreenTouchable (boolean screenTouchable ) {
82+ private void setScreenTouchable (boolean screenTouchable ) {
6283 this .mScreenTouchable = screenTouchable ;
6384 }
6485
86+ /**
87+ * Returns true if no animation is in progress currently. Can be used to disable any events
88+ * if they are not allowed during an animation. Returns false if an animation is in progress.
89+ *
90+ * @return - true if animation in progress, false otherwise
91+ */
6592 public boolean isScreenTouchable () {
6693 return mScreenTouchable ;
6794 }
@@ -78,7 +105,7 @@ public CardStackAdapter(Context context) {
78105 mCardViews = new View [getCount ()];
79106 }
80107
81- public void addView (final int position ) {
108+ void addView (final int position ) {
82109 View root = createView (position , mParent );
83110 root .setOnTouchListener (this );
84111 root .setTag (R .id .cardstack_internal_position_tag , position );
@@ -101,14 +128,19 @@ public void addView(final int position) {
101128 mParent .addView (root );
102129 }
103130
104- public float getCardFinalY (int position ) {
131+ private float getCardFinalY (int position ) {
105132 return mScreenHeight - dp30 - ((getCount () - position ) * mCardGapBottom ) - mCardPaddingInternal ;
106133 }
107134
108135 private float getCardOriginalY (int position ) {
109136 return mParentPaddingTop + mCardGap * position ;
110137 }
111138
139+ /**
140+ * Resets all cards in {@link CardStackLayout} to their initial positions
141+ *
142+ * @param r Execute r.run() once the reset animation is done
143+ */
112144 public void resetCards (Runnable r ) {
113145 List <Animator > animations = new ArrayList <>(getCount ());
114146 for (int i = 0 ; i < getCount (); i ++) {
@@ -118,6 +150,13 @@ public void resetCards(Runnable r) {
118150 startAnimations (animations , r , true );
119151 }
120152
153+ /**
154+ * Plays together all animations passed in as parameter. Once animation is completed, r.run() is
155+ * executed. If parameter isReset is set to true, {@link #mSelectedCardPosition} is set to {@link #INVALID_CARD_POSITION}
156+ * @param animations
157+ * @param r
158+ * @param isReset
159+ */
121160 private void startAnimations (List <Animator > animations , final Runnable r , final boolean isReset ) {
122161 AnimatorSet animatorSet = new AnimatorSet ();
123162 animatorSet .playTogether (animations );
@@ -129,7 +168,7 @@ public void onAnimationEnd(Animator animation) {
129168 if (r != null ) r .run ();
130169 setScreenTouchable (true );
131170 if (isReset )
132- mSelectedCardPosition = - 1 ;
171+ mSelectedCardPosition = INVALID_CARD_POSITION ;
133172 }
134173 });
135174 animatorSet .start ();
@@ -153,13 +192,13 @@ public boolean onTouch(View v, MotionEvent event) {
153192 mTouchDistance = 0 ;
154193 break ;
155194 case MotionEvent .ACTION_MOVE :
156- if (mSelectedCardPosition == - 1 )
195+ if (mSelectedCardPosition == INVALID_CARD_POSITION )
157196 moveCards (positionOfCardToMove , y - mTouchFirstY );
158197 mTouchDistance += Math .abs (y - mTouchPrevY );
159198 break ;
160199 case MotionEvent .ACTION_CANCEL :
161200 case MotionEvent .ACTION_UP :
162- if (mTouchDistance < dp8 && Math .abs (y - mTouchFirstY ) < dp8 && mSelectedCardPosition == - 1 ) {
201+ if (mTouchDistance < dp8 && Math .abs (y - mTouchFirstY ) < dp8 && mSelectedCardPosition == INVALID_CARD_POSITION ) {
163202 onClick (v );
164203 } else {
165204 resetCards ();
@@ -178,7 +217,7 @@ public void onClick(final View v) {
178217 return ;
179218 }
180219 setScreenTouchable (false );
181- if (mSelectedCardPosition == - 1 ) {
220+ if (mSelectedCardPosition == INVALID_CARD_POSITION ) {
182221 mSelectedCardPosition = (int ) v .getTag (R .id .cardstack_internal_position_tag );
183222
184223 List <Animator > animations = new ArrayList <>(getCount ());
@@ -203,7 +242,7 @@ public void run() {
203242 }
204243 }
205244
206- public void moveCards (int positionOfCardToMove , float diff ) {
245+ private void moveCards (int positionOfCardToMove , float diff ) {
207246 if (diff < 0 || positionOfCardToMove < 0 || positionOfCardToMove >= getCount ()) return ;
208247 for (int i = positionOfCardToMove ; i < getCount (); i ++) {
209248 final View child = mCardViews [i ];
@@ -220,7 +259,12 @@ public void moveCards(int positionOfCardToMove, float diff) {
220259 }
221260 }
222261
223- public void setAdapterParams (CardStackLayout cardStackLayout ) {
262+ /**
263+ * Provides an API to {@link CardStackLayout} to set the parameters provided to it in its XML
264+ *
265+ * @param cardStackLayout Parent of all cards
266+ */
267+ void setAdapterParams (CardStackLayout cardStackLayout ) {
224268 mParent = cardStackLayout ;
225269 mCardGapBottom = cardStackLayout .getCardGapBottom ();
226270 mCardGap = cardStackLayout .getCardGap ();
@@ -233,11 +277,43 @@ public void setAdapterParams(CardStackLayout cardStackLayout) {
233277 fullCardHeight = (int ) (mScreenHeight - dp30 - dp8 - getCount () * mCardGapBottom );
234278 }
235279
280+ /**
281+ * Resets all cards in {@link CardStackLayout} to their initial positions
282+ */
236283 public void resetCards () {
237284 resetCards (null );
238285 }
239286
287+ /**
288+ * Returns false if all the cards are in their initial position i.e. no card is selected
289+ *
290+ * Returns true if the {@link CardStackLayout} has a card selected and all other cards are
291+ * at the bottom of the screen.
292+ *
293+ * @return true if any card is selected, false otherwise
294+ */
240295 public boolean isCardSelected () {
241- return mSelectedCardPosition != -1 ;
296+ return mSelectedCardPosition != INVALID_CARD_POSITION ;
297+ }
298+
299+ /**
300+ * Returns the position of selected card. If no card
301+ * is selected, returns {@link #INVALID_CARD_POSITION}
302+ */
303+ public int getSelectedCardPosition () {
304+ return mSelectedCardPosition ;
305+ }
306+
307+ /**
308+ * Since there is no view recycling in {@link CardStackLayout}, we maintain an instance of every
309+ * view that is set for every position. This method returns a view at the requested position.
310+ *
311+ * @param position Position of card in {@link CardStackLayout}
312+ * @return View at requested position
313+ */
314+ public View getCardView (int position ) {
315+ if (mCardViews == null ) return null ;
316+
317+ return mCardViews [position ];
242318 }
243- }
319+ }
0 commit comments