Skip to content

Commit dcf3cd7

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

1 file changed

Lines changed: 31 additions & 47 deletions

File tree

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

Lines changed: 31 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,19 @@ 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+
setMaxHeight(Integer.MAX_VALUE);
160+
setMinHeight(0);
161+
178162
// if fully expanded, set height to WRAP_CONTENT, because when rotating the device
179163
// the height calculated with this ValueAnimator isn't correct anymore
180164
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
@@ -209,44 +193,44 @@ public boolean collapse()
209193
{
210194
if (this.expanded && !this.animating && this.maxLines >= 0)
211195
{
212-
this.animating = true;
213-
214196
// notify listener
215197
this.notifyOnCollapse();
216198

217-
// get expanded height
199+
// measure expanded height
218200
final int expandedHeight = this.getMeasuredHeight();
219201

202+
// indicate that we are now animating
203+
this.animating = true;
204+
220205
// animate from expanded height to collapsed height
221206
final ValueAnimator valueAnimator = ValueAnimator.ofInt(expandedHeight, this.collapsedHeight);
222207
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
223208
{
224209
@Override
225210
public void onAnimationUpdate(final ValueAnimator animation)
226211
{
227-
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
228-
layoutParams.height = (int) animation.getAnimatedValue();
229-
ExpandableTextView.this.setLayoutParams(layoutParams);
212+
ExpandableTextView.this.setHeight((int) animation.getAnimatedValue());
230213
}
231214
});
232215

216+
// wait for the animation to end
233217
valueAnimator.addListener(new AnimatorListenerAdapter()
234218
{
235219
@Override
236220
public void onAnimationEnd(final Animator animation)
237221
{
238-
// set maxLines to original value
222+
// keep track of current status
223+
ExpandableTextView.this.expanded = false;
224+
ExpandableTextView.this.animating = false;
225+
226+
// set maxLines back to original value
239227
ExpandableTextView.this.setMaxLines(ExpandableTextView.this.maxLines);
240228

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
229+
// if fully collapsed, set height back to WRAP_CONTENT, because when rotating the device
230+
// the height previously calculated with this ValueAnimator isn't correct anymore
243231
final ViewGroup.LayoutParams layoutParams = ExpandableTextView.this.getLayoutParams();
244232
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
245233
ExpandableTextView.this.setLayoutParams(layoutParams);
246-
247-
// keep track of current status
248-
ExpandableTextView.this.expanded = false;
249-
ExpandableTextView.this.animating = false;
250234
}
251235
});
252236

0 commit comments

Comments
 (0)