77import android .content .Context ;
88import android .content .res .TypedArray ;
99import android .os .Build ;
10+ import android .support .annotation .NonNull ;
11+ import android .support .annotation .Nullable ;
1012import android .util .AttributeSet ;
1113import android .view .ViewGroup ;
1214import android .view .animation .AccelerateDecelerateInterpolator ;
1315import android .widget .TextView ;
1416
1517import java .lang .reflect .Field ;
18+ import java .util .ArrayList ;
19+ import java .util .List ;
1620
1721import at .blogc .expandabletextview .BuildConfig ;
1822import at .blogc .expandabletextview .R ;
@@ -39,7 +43,7 @@ public class ExpandableTextView extends TextView
3943 // copy off TextView.LINES
4044 private static final int MAXMODE_LINES = 1 ;
4145
42- private OnExpandListener onExpandListener ;
46+ private final List < OnExpandListener > onExpandListeners ;
4347 private TimeInterpolator expandInterpolator ;
4448 private TimeInterpolator collapseInterpolator ;
4549
@@ -71,6 +75,9 @@ public ExpandableTextView(final Context context, final AttributeSet attrs, final
7175 // keep the original value of maxLines
7276 this .maxLines = this .getMaxLines ();
7377
78+ // create bucket for OnExpandListener instances
79+ this .onExpandListeners = new ArrayList <>();
80+
7481 // create default interpolators
7582 this .expandInterpolator = new AccelerateDecelerateInterpolator ();
7683 this .collapseInterpolator = new AccelerateDecelerateInterpolator ();
@@ -102,6 +109,9 @@ public int getMaxLines()
102109 }
103110 }
104111
112+
113+ //region public helper methods
114+
105115 /**
106116 * Toggle the expanded state of this {@link ExpandableTextView}.
107117 * @return true if toggled, false otherwise.
@@ -124,10 +134,7 @@ public boolean expand()
124134 this .animating = true ;
125135
126136 // notify listener
127- if (this .onExpandListener != null )
128- {
129- this .onExpandListener .onExpand (this );
130- }
137+ this .notifyOnExpand ();
131138
132139 // get collapsed height
133140 this .measure
@@ -205,10 +212,7 @@ public boolean collapse()
205212 this .animating = true ;
206213
207214 // notify listener
208- if (this .onExpandListener != null )
209- {
210- this .onExpandListener .onCollapse (this );
211- }
215+ this .notifyOnCollapse ();
212216
213217 // get expanded height
214218 final int expandedHeight = this .getMeasuredHeight ();
@@ -260,6 +264,10 @@ public void onAnimationEnd(final Animator animation)
260264 return false ;
261265 }
262266
267+ //endregion
268+
269+ //region public getters and setters
270+
263271 /**
264272 * Sets the duration of the expand / collapse animation.
265273 * @param animationDuration duration in milliseconds.
@@ -270,21 +278,21 @@ public void setAnimationDuration(final long animationDuration)
270278 }
271279
272280 /**
273- * Sets a listener which receives updates about this {@link ExpandableTextView}.
281+ * Adds a listener which receives updates about this {@link ExpandableTextView}.
274282 * @param onExpandListener the listener.
275283 */
276- public void setOnExpandListener (final OnExpandListener onExpandListener )
284+ public void addOnExpandListener (final OnExpandListener onExpandListener )
277285 {
278- this .onExpandListener = onExpandListener ;
286+ this .onExpandListeners . add ( onExpandListener ) ;
279287 }
280288
281289 /**
282- * Returns the {@link OnExpandListener }.
283- * @return the listener.
290+ * Removes a listener which receives updates about this {@link ExpandableTextView }.
291+ * @param onExpandListener the listener.
284292 */
285- public OnExpandListener getOnExpandListener ( )
293+ public void removeOnExpandListener ( final OnExpandListener onExpandListener )
286294 {
287- return this .onExpandListener ;
295+ this .onExpandListeners . remove ( onExpandListener ) ;
288296 }
289297
290298 /**
@@ -342,6 +350,44 @@ public boolean isExpanded()
342350 return this .expanded ;
343351 }
344352
353+ //endregion
354+
355+ /**
356+ * This method will notify the listener about this view being expanded.
357+ */
358+ private void notifyOnCollapse ()
359+ {
360+ for (final OnExpandListener onExpandListener : this .onExpandListeners )
361+ {
362+ onExpandListener .onCollapse (this );
363+ }
364+ }
365+
366+ /**
367+ * This method will notify the listener about this view being collapsed.
368+ */
369+ private void notifyOnExpand ()
370+ {
371+ for (final OnExpandListener onExpandListener : this .onExpandListeners )
372+ {
373+ onExpandListener .onExpand (this );
374+ }
375+ }
376+
377+ /**
378+ * This method will notify the listener about this change.
379+ * @param canExpand
380+ */
381+ private void notifyExpandBehaviourChanged (final boolean canExpand )
382+ {
383+ for (final OnExpandListener onExpandListener : this .onExpandListeners )
384+ {
385+ onExpandListener .onExpandBehaviourChanged (this , canExpand );
386+ }
387+ }
388+
389+ //region public interfaces
390+
345391 /**
346392 * Interface definition for a callback to be invoked when
347393 * a {@link ExpandableTextView} is expanded or collapsed.
@@ -352,12 +398,34 @@ public interface OnExpandListener
352398 * The {@link ExpandableTextView} is being expanded.
353399 * @param view the textview
354400 */
355- void onExpand (ExpandableTextView view );
401+ void onExpand (@ NonNull ExpandableTextView view );
356402
357403 /**
358404 * The {@link ExpandableTextView} is being collapsed.
359405 * @param view the textview
360406 */
361- void onCollapse (ExpandableTextView view );
407+ void onCollapse (@ NonNull ExpandableTextView view );
362408 }
409+
410+ /**
411+ * Simple implementation of the {@link OnExpandListener} interface with stub
412+ * implementations of each method. Extend this if you do not intend to override
413+ * every method of {@link OnExpandListener}.
414+ */
415+ public static class SimpleOnExpandListener implements OnExpandListener
416+ {
417+ @ Override
418+ public void onExpand (@ NonNull final ExpandableTextView view )
419+ {
420+ // empty implementation
421+ }
422+
423+ @ Override
424+ public void onCollapse (@ NonNull final ExpandableTextView view )
425+ {
426+ // empty implementation
427+ }
428+ }
429+
430+ //endregion
363431}
0 commit comments