19
19
public class ExpandableTextView extends TextView
20
20
{
21
21
private static final int DEFAULT_DURATION = 750 ;
22
- private static final int LINES = 1 ;
22
+ private static final int MAXMODE_LINES = 1 ;
23
23
24
24
private OnExpandListener onExpandListener ;
25
- private final int duration ;
25
+
26
+ private long animationDuration ;
27
+ private boolean animating ;
26
28
private boolean expanded ;
27
29
private int maxLines ;
28
30
private int originalHeight ;
@@ -43,7 +45,7 @@ public ExpandableTextView(Context context, AttributeSet attrs, int defStyle)
43
45
44
46
// read attributes
45
47
final TypedArray attributes = context .obtainStyledAttributes (attrs , R .styleable .ExpandableTextView , defStyle , 0 );
46
- this .duration = attributes .getInt (R .styleable .ExpandableTextView_duration , DEFAULT_DURATION );
48
+ this .animationDuration = attributes .getInt (R .styleable .ExpandableTextView_animation_duration , DEFAULT_DURATION );
47
49
attributes .recycle ();
48
50
49
51
// keep the original value of maxLines
@@ -68,14 +70,18 @@ public int getMaxLines()
68
70
final int mMaxModeValue = (int ) mMaxMode .get (this );
69
71
final int mMaximumValue = (int ) mMaximum .get (this );
70
72
71
- return mMaxModeValue == LINES ? mMaximumValue : -1 ;
73
+ return mMaxModeValue == MAXMODE_LINES ? mMaximumValue : -1 ;
72
74
}
73
75
catch (final Exception e )
74
76
{
75
77
return -1 ;
76
78
}
77
79
}
78
80
81
+ /**
82
+ * Toggle the expanded state of this {@link ExpandableTextView}.
83
+ * @return true if toggled, false otherwise.
84
+ */
79
85
public boolean toggle ()
80
86
{
81
87
if (this .expanded )
@@ -86,11 +92,15 @@ public boolean toggle()
86
92
return this .expand ();
87
93
}
88
94
95
+ /**
96
+ * Expand this {@link ExpandableTextView}.
97
+ * @return true if expanded, false otherwise.
98
+ */
89
99
public boolean expand ()
90
100
{
91
- if (!this .expanded && this .maxLines >= 0 )
101
+ if (!this .expanded && ! this . animating && this .maxLines >= 0 )
92
102
{
93
- this .expanded = true ;
103
+ this .animating = true ;
94
104
95
105
// notify listener
96
106
if (this .onExpandListener != null )
@@ -130,10 +140,19 @@ public void onAnimationUpdate(final ValueAnimator animation)
130
140
ExpandableTextView .this .setLayoutParams (layoutParams );
131
141
}
132
142
});
143
+ valueAnimator .addListener (new AnimatorListener ()
144
+ {
145
+ @ Override
146
+ public void onAnimationEnd (final Animator animation )
147
+ {
148
+ ExpandableTextView .this .expanded = true ;
149
+ ExpandableTextView .this .animating = false ;
150
+ }
151
+ });
133
152
134
153
// start the animation
135
154
valueAnimator
136
- .setDuration (this .duration )
155
+ .setDuration (this .animationDuration )
137
156
.start ();
138
157
139
158
return true ;
@@ -142,11 +161,15 @@ public void onAnimationUpdate(final ValueAnimator animation)
142
161
return false ;
143
162
}
144
163
164
+ /**
165
+ * Collapse this {@link TextView}.
166
+ * @return true if collapsed, false otherwise.
167
+ */
145
168
public boolean collapse ()
146
169
{
147
- if (this .expanded && this .maxLines >= 0 )
170
+ if (this .expanded && ! this . animating && this .maxLines >= 0 )
148
171
{
149
- this .expanded = false ;
172
+ this .animating = true ;
150
173
151
174
// notify listener
152
175
if (this .onExpandListener != null )
@@ -175,12 +198,15 @@ public void onAnimationEnd(final Animator animation)
175
198
{
176
199
// set maxLines to original value
177
200
ExpandableTextView .this .setMaxLines (ExpandableTextView .this .maxLines );
201
+
202
+ ExpandableTextView .this .expanded = false ;
203
+ ExpandableTextView .this .animating = false ;
178
204
}
179
205
});
180
206
181
207
// start the animation
182
208
valueAnimator
183
- .setDuration (this .duration )
209
+ .setDuration (this .animationDuration )
184
210
.start ();
185
211
186
212
return true ;
@@ -189,16 +215,37 @@ public void onAnimationEnd(final Animator animation)
189
215
return false ;
190
216
}
191
217
218
+ /**
219
+ * Sets the duration of the expand / collapse animation.
220
+ * @param animationDuration duration in milliseconds.
221
+ */
222
+ public void setAnimationDuration (final long animationDuration )
223
+ {
224
+ this .animationDuration = animationDuration ;
225
+ }
226
+
227
+ /**
228
+ * Sets a listener which receives updates about this {@link ExpandableTextView}.
229
+ * @param onExpandListener the listener.
230
+ */
192
231
public void setOnExpandListener (final OnExpandListener onExpandListener )
193
232
{
194
233
this .onExpandListener = onExpandListener ;
195
234
}
196
235
236
+ /**
237
+ * Returns the {@link OnExpandListener}.
238
+ * @return the listener.
239
+ */
197
240
public OnExpandListener getOnExpandListener ()
198
241
{
199
242
return onExpandListener ;
200
243
}
201
244
245
+ /**
246
+ * Is this {@link ExpandableTextView} expanded or not?
247
+ * @return true if expanded, false if collapsed.
248
+ */
202
249
public boolean isExpanded ()
203
250
{
204
251
return this .expanded ;
0 commit comments