Skip to content

Commit b3b8148

Browse files
authored
Merge pull request Manabu-GT#35 from gergely-sallai/master
Enable support for TextView expand/collapse toggle and custom Ids
2 parents abc2036 + 3480e8c commit b3b8148

2 files changed

Lines changed: 129 additions & 26 deletions

File tree

lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java

Lines changed: 120 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.graphics.drawable.Drawable;
2525
import android.os.Build;
2626
import android.support.annotation.DrawableRes;
27+
import android.support.annotation.IdRes;
2728
import android.support.annotation.NonNull;
2829
import android.support.annotation.Nullable;
2930
import 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
}

lib/src/main/res/values/attrs.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44
<attr name="maxCollapsedLines" format="integer"/>
55
<attr name="animDuration" format="integer"/>
66
<attr name="animAlphaStart" format="float"/>
7-
<attr name="expandDrawable" format="reference"/>
8-
<attr name="collapseDrawable" format="reference"/>
7+
<attr name="expandIndicator" format="reference"/>
8+
<attr name="collapseIndicator" format="reference"/>
9+
<attr name="expandToggleType" format="enum">
10+
<enum name="ImageButton" value="0"/>
11+
<enum name="TextView" value="1"/>
12+
</attr>
13+
<attr name="expandableTextId" format="reference"/>
14+
<attr name="expandCollapseToggleId" format="reference"/>
15+
<attr name="expandToggleOnTextClick" format="boolean"/>
916
</declare-styleable>
1017
</resources>

0 commit comments

Comments
 (0)