Skip to content

Commit 79524f6

Browse files
committed
[EXPTXTANDR-6] Github: Add support for Android O
1 parent f09aff4 commit 79524f6

1 file changed

Lines changed: 32 additions & 47 deletions

File tree

expandabletextview/src/main/java/at/blogc/android/views/ExpandableTextView.java

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,21 @@
66
import android.animation.ValueAnimator;
77
import android.content.Context;
88
import android.content.res.TypedArray;
9-
import android.os.Build;
109
import android.support.annotation.NonNull;
1110
import android.support.annotation.Nullable;
1211
import android.util.AttributeSet;
1312
import android.view.ViewGroup;
1413
import android.view.animation.AccelerateDecelerateInterpolator;
1514
import android.widget.TextView;
1615

17-
import java.lang.reflect.Field;
1816
import java.util.ArrayList;
1917
import java.util.List;
2018

2119
import at.blogc.expandabletextview.BuildConfig;
2220
import at.blogc.expandabletextview.R;
2321

2422
/**
25-
* Copyright (C) 2016 Cliff Ophalvens (Blogc.at)
23+
* Copyright (C) 2017 Cliff Ophalvens (Blogc.at)
2624
*
2725
* Licensed under the Apache License, Version 2.0 (the "License");
2826
* you may not use this file except in compliance with the License.
@@ -40,9 +38,6 @@
4038
*/
4139
public class ExpandableTextView extends TextView
4240
{
43-
// copy off TextView.LINES
44-
private static final int MAXMODE_LINES = 1;
45-
4641
private final List<OnExpandListener> onExpandListeners;
4742
private TimeInterpolator expandInterpolator;
4843
private TimeInterpolator collapseInterpolator;
@@ -75,7 +70,7 @@ public ExpandableTextView(final Context context, @Nullable final AttributeSet at
7570
// keep the original value of maxLines
7671
this.maxLines = this.getMaxLines();
7772

78-
// create bucket for OnExpandListener instances
73+
// create bucket of OnExpandListener instances
7974
this.onExpandListeners = new ArrayList<>();
8075

8176
// create default interpolators
@@ -84,32 +79,18 @@ public ExpandableTextView(final Context context, @Nullable final AttributeSet at
8479
}
8580

8681
@Override
87-
public int getMaxLines()
82+
protected void onMeasure(final int widthMeasureSpec, int heightMeasureSpec)
8883
{
89-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
84+
// if this TextView is collapsed and maxLines = 0,
85+
// than make its height equals to zero
86+
if (this.maxLines == 0 && !this.expanded && !this.animating)
9087
{
91-
return super.getMaxLines();
88+
heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
9289
}
9390

94-
try
95-
{
96-
final Field mMaxMode = TextView.class.getField("mMaxMode");
97-
mMaxMode.setAccessible(true);
98-
final Field mMaximum = TextView.class.getField("mMaximum");
99-
mMaximum.setAccessible(true);
100-
101-
final int mMaxModeValue = (int) mMaxMode.get(this);
102-
final int mMaximumValue = (int) mMaximum.get(this);
103-
104-
return mMaxModeValue == MAXMODE_LINES ? mMaximumValue : -1;
105-
}
106-
catch (final Exception e)
107-
{
108-
return -1;
109-
}
91+
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
11092
}
11193

112-
11394
//region public helper methods
11495

11596
/**
@@ -131,12 +112,10 @@ public boolean expand()
131112
{
132113
if (!this.expanded && !this.animating && this.maxLines >= 0)
133114
{
134-
this.animating = true;
135-
136115
// notify listener
137116
this.notifyOnExpand();
138117

139-
// get collapsed height
118+
// measure collapsed height
140119
this.measure
141120
(
142121
MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), MeasureSpec.EXACTLY),
@@ -145,10 +124,13 @@ public boolean expand()
145124

146125
this.collapsedHeight = this.getMeasuredHeight();
147126

127+
// indicate that we are now animating
128+
this.animating = true;
129+
148130
// set maxLines to MAX Integer, so we can calculate the expanded height
149131
this.setMaxLines(Integer.MAX_VALUE);
150132

151-
// get expanded height
133+
// measure expanded height
152134
this.measure
153135
(
154136
MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), MeasureSpec.EXACTLY),
@@ -164,17 +146,20 @@ public boolean expand()
164146
@Override
165147
public void onAnimationUpdate(final ValueAnimator animation)
166148
{
167-
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
168-
layoutParams.height = (int) animation.getAnimatedValue();
169-
ExpandableTextView.this.setLayoutParams(layoutParams);
149+
ExpandableTextView.this.setHeight((int) animation.getAnimatedValue());
170150
}
171151
});
172152

153+
// wait for the animation to end
173154
valueAnimator.addListener(new AnimatorListenerAdapter()
174155
{
175156
@Override
176157
public void onAnimationEnd(final Animator animation)
177158
{
159+
// reset min & max height (previously set with setHeight() method)
160+
ExpandableTextView.this.setMaxHeight(Integer.MAX_VALUE);
161+
ExpandableTextView.this.setMinHeight(0);
162+
178163
// if fully expanded, set height to WRAP_CONTENT, because when rotating the device
179164
// the height calculated with this ValueAnimator isn't correct anymore
180165
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
@@ -209,44 +194,44 @@ public boolean collapse()
209194
{
210195
if (this.expanded && !this.animating && this.maxLines >= 0)
211196
{
212-
this.animating = true;
213-
214197
// notify listener
215198
this.notifyOnCollapse();
216199

217-
// get expanded height
200+
// measure expanded height
218201
final int expandedHeight = this.getMeasuredHeight();
219202

203+
// indicate that we are now animating
204+
this.animating = true;
205+
220206
// animate from expanded height to collapsed height
221207
final ValueAnimator valueAnimator = ValueAnimator.ofInt(expandedHeight, this.collapsedHeight);
222208
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
223209
{
224210
@Override
225211
public void onAnimationUpdate(final ValueAnimator animation)
226212
{
227-
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
228-
layoutParams.height = (int) animation.getAnimatedValue();
229-
ExpandableTextView.this.setLayoutParams(layoutParams);
213+
ExpandableTextView.this.setHeight((int) animation.getAnimatedValue());
230214
}
231215
});
232216

217+
// wait for the animation to end
233218
valueAnimator.addListener(new AnimatorListenerAdapter()
234219
{
235220
@Override
236221
public void onAnimationEnd(final Animator animation)
237222
{
238-
// set maxLines to original value
223+
// keep track of current status
224+
ExpandableTextView.this.expanded = false;
225+
ExpandableTextView.this.animating = false;
226+
227+
// set maxLines back to original value
239228
ExpandableTextView.this.setMaxLines(ExpandableTextView.this.maxLines);
240229

241-
// if fully collapsed, set height to WRAP_CONTENT, because when rotating the device
242-
// the height calculated with this ValueAnimator isn't correct anymore
230+
// if fully collapsed, set height back to WRAP_CONTENT, because when rotating the device
231+
// the height previously calculated with this ValueAnimator isn't correct anymore
243232
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
244233
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
245234
ExpandableTextView.this.setLayoutParams(layoutParams);
246-
247-
// keep track of current status
248-
ExpandableTextView.this.expanded = false;
249-
ExpandableTextView.this.animating = false;
250235
}
251236
});
252237

0 commit comments

Comments
 (0)