2424import android .graphics .drawable .Drawable ;
2525import android .os .Build ;
2626import android .support .annotation .DrawableRes ;
27+ import android .support .annotation .IdRes ;
2728import android .support .annotation .NonNull ;
2829import android .support .annotation .Nullable ;
2930import android .text .TextUtils ;
@@ -44,6 +45,12 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList
4445
4546 private static final String TAG = ExpandableTextView .class .getSimpleName ();
4647
48+ private static final int EXPAND_INDICATOR_IMAGE_BUTTON = 0 ;
49+
50+ private static final int EXPAND_INDICATOR_TEXT_VIEW = 1 ;
51+
52+ private static final int DEFAULT_TOGGLE_TYPE = EXPAND_INDICATOR_IMAGE_BUTTON ;
53+
4754 /* The default number of lines */
4855 private static final int MAX_COLLAPSED_LINES = 8 ;
4956
@@ -55,7 +62,7 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList
5562
5663 protected TextView mTv ;
5764
58- protected ImageButton mButton ; // Button to expand/collapse
65+ protected View mToggleView ; // View to expand/collapse
5966
6067 private boolean mRelayout ;
6168
@@ -69,16 +76,22 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList
6976
7077 private int mMarginBetweenTxtAndBottom ;
7178
72- private Drawable mExpandDrawable ;
73-
74- private Drawable mCollapseDrawable ;
79+ private ExpandIndicatorController mExpandIndicatorController ;
7580
7681 private int mAnimationDuration ;
7782
7883 private float mAnimAlphaStart ;
7984
8085 private boolean mAnimating ;
8186
87+ @ IdRes
88+ private int mExpandableTextId = R .id .expandable_text ;
89+
90+ @ IdRes
91+ private int mExpandCollapseToggleId = R .id .expand_collapse ;
92+
93+ private boolean mExpandToggleOnTextClick ;
94+
8295 /* Listener for callback */
8396 private OnExpandStateChangeListener mListener ;
8497
@@ -111,12 +124,12 @@ public void setOrientation(int orientation){
111124
112125 @ Override
113126 public void onClick (View view ) {
114- if (mButton .getVisibility () != View .VISIBLE ) {
127+ if (mToggleView .getVisibility () != View .VISIBLE ) {
115128 return ;
116129 }
117130
118131 mCollapsed = !mCollapsed ;
119- mButton . setImageDrawable (mCollapsed ? mExpandDrawable : mCollapseDrawable );
132+ mExpandIndicatorController . changeState (mCollapsed );
120133
121134 if (mCollapsedStatus != null ) {
122135 mCollapsedStatus .put (mPosition , mCollapsed );
@@ -168,6 +181,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) {
168181
169182 @ Override
170183 protected void onFinishInflate () {
184+ super .onFinishInflate ();
171185 findViews ();
172186 }
173187
@@ -182,7 +196,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
182196
183197 // Setup with optimistic case
184198 // i.e. Everything fits. No button needed
185- mButton .setVisibility (View .GONE );
199+ mToggleView .setVisibility (View .GONE );
186200 mTv .setMaxLines (Integer .MAX_VALUE );
187201
188202 // Measure
@@ -201,7 +215,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
201215 if (mCollapsed ) {
202216 mTv .setMaxLines (mMaxCollapsedLines );
203217 }
204- mButton .setVisibility (View .VISIBLE );
218+ mToggleView .setVisibility (View .VISIBLE );
205219
206220 // Re-measure with new setup
207221 super .onMeasure (widthMeasureSpec , heightMeasureSpec );
@@ -227,6 +241,9 @@ public void setText(@Nullable CharSequence text) {
227241 mRelayout = true ;
228242 mTv .setText (text );
229243 setVisibility (TextUtils .isEmpty (text ) ? View .GONE : View .VISIBLE );
244+ clearAnimation ();
245+ getLayoutParams ().height = ViewGroup .LayoutParams .WRAP_CONTENT ;
246+ requestLayout ();
230247 }
231248
232249 public void setText (@ Nullable CharSequence text , @ NonNull SparseBooleanArray collapsedStatus , int position ) {
@@ -235,10 +252,8 @@ public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray col
235252 boolean isCollapsed = collapsedStatus .get (position , true );
236253 clearAnimation ();
237254 mCollapsed = isCollapsed ;
238- mButton . setImageDrawable (mCollapsed ? mExpandDrawable : mCollapseDrawable );
255+ mExpandIndicatorController . changeState (mCollapsed );
239256 setText (text );
240- getLayoutParams ().height = ViewGroup .LayoutParams .WRAP_CONTENT ;
241- requestLayout ();
242257 }
243258
244259 @ Nullable
@@ -254,15 +269,11 @@ private void init(AttributeSet attrs) {
254269 mMaxCollapsedLines = typedArray .getInt (R .styleable .ExpandableTextView_maxCollapsedLines , MAX_COLLAPSED_LINES );
255270 mAnimationDuration = typedArray .getInt (R .styleable .ExpandableTextView_animDuration , DEFAULT_ANIM_DURATION );
256271 mAnimAlphaStart = typedArray .getFloat (R .styleable .ExpandableTextView_animAlphaStart , DEFAULT_ANIM_ALPHA_START );
257- mExpandDrawable = typedArray .getDrawable (R .styleable .ExpandableTextView_expandDrawable );
258- mCollapseDrawable = typedArray .getDrawable (R .styleable .ExpandableTextView_collapseDrawable );
272+ mExpandableTextId = typedArray .getResourceId (R .styleable .ExpandableTextView_expandableTextId , R .id .expandable_text );
273+ mExpandCollapseToggleId = typedArray .getResourceId (R .styleable .ExpandableTextView_expandCollapseToggleId , R .id .expand_collapse );
274+ mExpandToggleOnTextClick = typedArray .getBoolean (R .styleable .ExpandableTextView_expandToggleOnTextClick , true );
259275
260- if (mExpandDrawable == null ) {
261- mExpandDrawable = getDrawable (getContext (), R .drawable .ic_expand_more_black_12dp );
262- }
263- if (mCollapseDrawable == null ) {
264- mCollapseDrawable = getDrawable (getContext (), R .drawable .ic_expand_less_black_12dp );
265- }
276+ mExpandIndicatorController = setupExpandToggleController (getContext (), typedArray );
266277
267278 typedArray .recycle ();
268279
@@ -274,11 +285,16 @@ private void init(AttributeSet attrs) {
274285 }
275286
276287 private void findViews () {
277- mTv = (TextView ) findViewById (R .id .expandable_text );
278- mTv .setOnClickListener (this );
279- mButton = (ImageButton ) findViewById (R .id .expand_collapse );
280- mButton .setImageDrawable (mCollapsed ? mExpandDrawable : mCollapseDrawable );
281- mButton .setOnClickListener (this );
288+ mTv = (TextView ) findViewById (mExpandableTextId );
289+ if (mExpandToggleOnTextClick ) {
290+ mTv .setOnClickListener (this );
291+ } else {
292+ mTv .setOnClickListener (null );
293+ }
294+ mToggleView = findViewById (mExpandCollapseToggleId );
295+ mExpandIndicatorController .setView (mToggleView );
296+ mExpandIndicatorController .changeState (mCollapsed );
297+ mToggleView .setOnClickListener (this );
282298 }
283299
284300 private static boolean isPostHoneycomb () {
@@ -318,6 +334,34 @@ private static int getRealTextViewHeight(@NonNull TextView textView) {
318334 return textHeight + padding ;
319335 }
320336
337+ private static ExpandIndicatorController setupExpandToggleController (@ NonNull Context context , TypedArray typedArray ) {
338+ final int expandToggleType = typedArray .getInt (R .styleable .ExpandableTextView_expandToggleType , DEFAULT_TOGGLE_TYPE );
339+ final ExpandIndicatorController expandIndicatorController ;
340+ switch (expandToggleType ) {
341+ case EXPAND_INDICATOR_IMAGE_BUTTON :
342+ Drawable expandDrawable = typedArray .getDrawable (R .styleable .ExpandableTextView_expandIndicator );
343+ Drawable collapseDrawable = typedArray .getDrawable (R .styleable .ExpandableTextView_collapseIndicator );
344+
345+ if (expandDrawable == null ) {
346+ expandDrawable = getDrawable (context , R .drawable .ic_expand_more_black_12dp );
347+ }
348+ if (collapseDrawable == null ) {
349+ collapseDrawable = getDrawable (context , R .drawable .ic_expand_less_black_12dp );
350+ }
351+ expandIndicatorController = new ImageButtonExpandController (expandDrawable , collapseDrawable );
352+ break ;
353+ case EXPAND_INDICATOR_TEXT_VIEW :
354+ String expandText = typedArray .getString (R .styleable .ExpandableTextView_expandIndicator );
355+ String collapseText = typedArray .getString (R .styleable .ExpandableTextView_collapseIndicator );
356+ expandIndicatorController = new TextViewExpandController (expandText , collapseText );
357+ break ;
358+ default :
359+ throw new IllegalStateException ("Must be of enum: ExpandableTextView_expandToggleType, one of EXPAND_INDICATOR_IMAGE_BUTTON or EXPAND_INDICATOR_TEXT_VIEW." );
360+ }
361+
362+ return expandIndicatorController ;
363+ }
364+
321365 class ExpandCollapseAnimation extends Animation {
322366 private final View mTargetView ;
323367 private final int mStartHeight ;
@@ -361,4 +405,56 @@ public interface OnExpandStateChangeListener {
361405 */
362406 void onExpandStateChanged (TextView textView , boolean isExpanded );
363407 }
408+
409+ interface ExpandIndicatorController {
410+ void changeState (boolean collapsed );
411+
412+ void setView (View toggleView );
413+ }
414+
415+ static class ImageButtonExpandController implements ExpandIndicatorController {
416+
417+ private final Drawable mExpandDrawable ;
418+ private final Drawable mCollapseDrawable ;
419+
420+ private ImageButton mImageButton ;
421+
422+ public ImageButtonExpandController (Drawable expandDrawable , Drawable collapseDrawable ) {
423+ mExpandDrawable = expandDrawable ;
424+ mCollapseDrawable = collapseDrawable ;
425+ }
426+
427+ @ Override
428+ public void changeState (boolean collapsed ) {
429+ mImageButton .setImageDrawable (collapsed ? mExpandDrawable : mCollapseDrawable );
430+ }
431+
432+ @ Override
433+ public void setView (View toggleView ) {
434+ mImageButton = (ImageButton ) toggleView ;
435+ }
436+ }
437+
438+ static class TextViewExpandController implements ExpandIndicatorController {
439+
440+ private final String mExpandText ;
441+ private final String mCollapseText ;
442+
443+ private TextView mTextView ;
444+
445+ public TextViewExpandController (String expandText , String collapseText ) {
446+ mExpandText = expandText ;
447+ mCollapseText = collapseText ;
448+ }
449+
450+ @ Override
451+ public void changeState (boolean collapsed ) {
452+ mTextView .setText (collapsed ? mExpandText : mCollapseText );
453+ }
454+
455+ @ Override
456+ public void setView (View toggleView ) {
457+ mTextView = (TextView ) toggleView ;
458+ }
459+ }
364460}
0 commit comments