@@ -47,7 +47,7 @@ public class ExpandableTextView extends TextView
47
47
private long animationDuration ;
48
48
private boolean animating ;
49
49
private boolean expanded ;
50
- private int originalHeight ;
50
+ private int collapsedHeight ;
51
51
52
52
public ExpandableTextView (final Context context )
53
53
{
@@ -108,12 +108,9 @@ public int getMaxLines()
108
108
*/
109
109
public boolean toggle ()
110
110
{
111
- if (this .expanded )
112
- {
113
- return this .collapse ();
114
- }
115
-
116
- return this .expand ();
111
+ return this .expanded
112
+ ? this .collapse ()
113
+ : this .expand ();
117
114
}
118
115
119
116
/**
@@ -132,28 +129,29 @@ public boolean expand()
132
129
this .onExpandListener .onExpand (this );
133
130
}
134
131
135
- // get original height
132
+ // get collapsed height
136
133
this .measure
137
134
(
138
135
MeasureSpec .makeMeasureSpec (this .getMeasuredWidth (), MeasureSpec .EXACTLY ),
139
136
MeasureSpec .makeMeasureSpec (0 , MeasureSpec .UNSPECIFIED )
140
137
);
141
138
142
- this .originalHeight = this .getMeasuredHeight ();
139
+ this .collapsedHeight = this .getMeasuredHeight ();
143
140
144
- // set maxLines to MAX Integer
141
+ // set maxLines to MAX Integer, so we can calculate the expanded height
145
142
this .setMaxLines (Integer .MAX_VALUE );
146
143
147
- // get new height
144
+ // get expanded height
148
145
this .measure
149
146
(
150
147
MeasureSpec .makeMeasureSpec (this .getMeasuredWidth (), MeasureSpec .EXACTLY ),
151
148
MeasureSpec .makeMeasureSpec (0 , MeasureSpec .UNSPECIFIED )
152
149
);
153
150
154
- final int fullHeight = this .getMeasuredHeight ();
151
+ final int expandedHeight = this .getMeasuredHeight ();
155
152
156
- final ValueAnimator valueAnimator = ValueAnimator .ofInt (this .originalHeight , fullHeight );
153
+ // animate from collapsed height to expanded height
154
+ final ValueAnimator valueAnimator = ValueAnimator .ofInt (this .collapsedHeight , expandedHeight );
157
155
valueAnimator .addUpdateListener (new ValueAnimator .AnimatorUpdateListener ()
158
156
{
159
157
@ Override
@@ -164,11 +162,19 @@ public void onAnimationUpdate(final ValueAnimator animation)
164
162
ExpandableTextView .this .setLayoutParams (layoutParams );
165
163
}
166
164
});
165
+
167
166
valueAnimator .addListener (new AnimatorListenerAdapter ()
168
167
{
169
168
@ Override
170
169
public void onAnimationEnd (final Animator animation )
171
170
{
171
+ // if fully expanded, set height to WRAP_CONTENT, because when rotating the device
172
+ // the height calculated with this ValueAnimator isn't correct anymore
173
+ final ViewGroup .LayoutParams layoutParams = ExpandableTextView .this .getLayoutParams ();
174
+ layoutParams .height = ViewGroup .LayoutParams .WRAP_CONTENT ;
175
+ ExpandableTextView .this .setLayoutParams (layoutParams );
176
+
177
+ // keep track of current status
172
178
ExpandableTextView .this .expanded = true ;
173
179
ExpandableTextView .this .animating = false ;
174
180
}
@@ -204,10 +210,11 @@ public boolean collapse()
204
210
this .onExpandListener .onCollapse (this );
205
211
}
206
212
207
- // get new height
208
- final int fullHeight = this .getMeasuredHeight ();
213
+ // get expanded height
214
+ final int expandedHeight = this .getMeasuredHeight ();
209
215
210
- final ValueAnimator valueAnimator = ValueAnimator .ofInt (fullHeight , this .originalHeight );
216
+ // animate from expanded height to collapsed height
217
+ final ValueAnimator valueAnimator = ValueAnimator .ofInt (expandedHeight , this .collapsedHeight );
211
218
valueAnimator .addUpdateListener (new ValueAnimator .AnimatorUpdateListener ()
212
219
{
213
220
@ Override
@@ -218,6 +225,7 @@ public void onAnimationUpdate(final ValueAnimator animation)
218
225
ExpandableTextView .this .setLayoutParams (layoutParams );
219
226
}
220
227
});
228
+
221
229
valueAnimator .addListener (new AnimatorListenerAdapter ()
222
230
{
223
231
@ Override
@@ -226,6 +234,13 @@ public void onAnimationEnd(final Animator animation)
226
234
// set maxLines to original value
227
235
ExpandableTextView .this .setMaxLines (ExpandableTextView .this .maxLines );
228
236
237
+ // if fully collapsed, set height to WRAP_CONTENT, because when rotating the device
238
+ // the height calculated with this ValueAnimator isn't correct anymore
239
+ final ViewGroup .LayoutParams layoutParams = ExpandableTextView .this .getLayoutParams ();
240
+ layoutParams .height = ViewGroup .LayoutParams .WRAP_CONTENT ;
241
+ ExpandableTextView .this .setLayoutParams (layoutParams );
242
+
243
+ // keep track of current status
229
244
ExpandableTextView .this .expanded = false ;
230
245
ExpandableTextView .this .animating = false ;
231
246
}
@@ -269,7 +284,7 @@ public void setOnExpandListener(final OnExpandListener onExpandListener)
269
284
*/
270
285
public OnExpandListener getOnExpandListener ()
271
286
{
272
- return onExpandListener ;
287
+ return this . onExpandListener ;
273
288
}
274
289
275
290
/**
@@ -327,9 +342,22 @@ public boolean isExpanded()
327
342
return this .expanded ;
328
343
}
329
344
345
+ /**
346
+ * Interface definition for a callback to be invoked when
347
+ * a {@link ExpandableTextView} is expanded or collapsed.
348
+ */
330
349
public interface OnExpandListener
331
350
{
351
+ /**
352
+ * The {@link ExpandableTextView} is being expanded.
353
+ * @param view the textview
354
+ */
332
355
void onExpand (ExpandableTextView view );
356
+
357
+ /**
358
+ * The {@link ExpandableTextView} is being collapsed.
359
+ * @param view the textview
360
+ */
333
361
void onCollapse (ExpandableTextView view );
334
362
}
335
363
}
0 commit comments