From 4cab78ab84ed393027c80967ea14e05190507569 Mon Sep 17 00:00:00 2001 From: Sallai Gergely Date: Mon, 8 Feb 2016 16:48:13 +0100 Subject: [PATCH 1/5] Call super.onFinishInflate() --- .../ms/square/android/expandabletextview/ExpandableTextView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java index 502fa88..a1fc066 100644 --- a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java +++ b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java @@ -168,6 +168,7 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { @Override protected void onFinishInflate() { + super.onFinishInflate(); findViews(); } From 97d65bb28a104623b7096d7e3003364feb3940ae Mon Sep 17 00:00:00 2001 From: Sallai Gergely Date: Mon, 8 Feb 2016 18:01:16 +0100 Subject: [PATCH 2/5] Added ability to chose "ExpandToggleType", the type of view to be the expand / collapse toggle. Currently ImageButton and TextView are supported, default is ImageButton. --- .../ExpandableTextView.java | 118 +++++++++++++++--- lib/src/main/res/values/attrs.xml | 8 +- 2 files changed, 104 insertions(+), 22 deletions(-) diff --git a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java index a1fc066..1312fb0 100644 --- a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java +++ b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java @@ -44,6 +44,12 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList private static final String TAG = ExpandableTextView.class.getSimpleName(); + private static final int EXPAND_INDICATOR_IMAGE_BUTTON = 0; + + private static final int EXPAND_INDICATOR_TEXT_VIEW = 1; + + private static final int DEFAULT_TOGGLE_TYPE = EXPAND_INDICATOR_IMAGE_BUTTON; + /* The default number of lines */ private static final int MAX_COLLAPSED_LINES = 8; @@ -55,7 +61,7 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList protected TextView mTv; - protected ImageButton mButton; // Button to expand/collapse + protected View mToggleView; // View to expand/collapse private boolean mRelayout; @@ -69,9 +75,7 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList private int mMarginBetweenTxtAndBottom; - private Drawable mExpandDrawable; - - private Drawable mCollapseDrawable; + private ExpandIndicatorController mExpandIndicatorController; private int mAnimationDuration; @@ -111,12 +115,12 @@ public void setOrientation(int orientation){ @Override public void onClick(View view) { - if (mButton.getVisibility() != View.VISIBLE) { + if (mToggleView.getVisibility() != View.VISIBLE) { return; } mCollapsed = !mCollapsed; - mButton.setImageDrawable(mCollapsed ? mExpandDrawable : mCollapseDrawable); + mExpandIndicatorController.changeState(mCollapsed); if (mCollapsedStatus != null) { mCollapsedStatus.put(mPosition, mCollapsed); @@ -183,7 +187,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Setup with optimistic case // i.e. Everything fits. No button needed - mButton.setVisibility(View.GONE); + mToggleView.setVisibility(View.GONE); mTv.setMaxLines(Integer.MAX_VALUE); // Measure @@ -202,7 +206,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (mCollapsed) { mTv.setMaxLines(mMaxCollapsedLines); } - mButton.setVisibility(View.VISIBLE); + mToggleView.setVisibility(View.VISIBLE); // Re-measure with new setup super.onMeasure(widthMeasureSpec, heightMeasureSpec); @@ -236,7 +240,7 @@ public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray col boolean isCollapsed = collapsedStatus.get(position, true); clearAnimation(); mCollapsed = isCollapsed; - mButton.setImageDrawable(mCollapsed ? mExpandDrawable : mCollapseDrawable); + mExpandIndicatorController.changeState(mCollapsed); setText(text); getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; requestLayout(); @@ -255,15 +259,8 @@ private void init(AttributeSet attrs) { mMaxCollapsedLines = typedArray.getInt(R.styleable.ExpandableTextView_maxCollapsedLines, MAX_COLLAPSED_LINES); mAnimationDuration = typedArray.getInt(R.styleable.ExpandableTextView_animDuration, DEFAULT_ANIM_DURATION); mAnimAlphaStart = typedArray.getFloat(R.styleable.ExpandableTextView_animAlphaStart, DEFAULT_ANIM_ALPHA_START); - mExpandDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_expandDrawable); - mCollapseDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_collapseDrawable); - if (mExpandDrawable == null) { - mExpandDrawable = getDrawable(getContext(), R.drawable.ic_expand_more_black_12dp); - } - if (mCollapseDrawable == null) { - mCollapseDrawable = getDrawable(getContext(), R.drawable.ic_expand_less_black_12dp); - } + mExpandIndicatorController = setupExpandToggleController(getContext(), typedArray); typedArray.recycle(); @@ -277,9 +274,10 @@ private void init(AttributeSet attrs) { private void findViews() { mTv = (TextView) findViewById(R.id.expandable_text); mTv.setOnClickListener(this); - mButton = (ImageButton) findViewById(R.id.expand_collapse); - mButton.setImageDrawable(mCollapsed ? mExpandDrawable : mCollapseDrawable); - mButton.setOnClickListener(this); + mToggleView = findViewById(R.id.expand_collapse); + mExpandIndicatorController.setView(mToggleView); + mExpandIndicatorController.changeState(mCollapsed); + mToggleView.setOnClickListener(this); } private static boolean isPostHoneycomb() { @@ -319,6 +317,34 @@ private static int getRealTextViewHeight(@NonNull TextView textView) { return textHeight + padding; } + private static ExpandIndicatorController setupExpandToggleController(@NonNull Context context, TypedArray typedArray) { + final int expandToggleType = typedArray.getInt(R.styleable.ExpandableTextView_expandToggleType, DEFAULT_TOGGLE_TYPE); + final ExpandIndicatorController expandIndicatorController; + switch (expandToggleType) { + case EXPAND_INDICATOR_IMAGE_BUTTON: + Drawable expandDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_expandIndicator); + Drawable collapseDrawable = typedArray.getDrawable(R.styleable.ExpandableTextView_collapseIndicator); + + if (expandDrawable == null) { + expandDrawable = getDrawable(context, R.drawable.ic_expand_more_black_12dp); + } + if (collapseDrawable == null) { + collapseDrawable = getDrawable(context, R.drawable.ic_expand_less_black_12dp); + } + expandIndicatorController = new ImageButtonExpandController(expandDrawable, collapseDrawable); + break; + case EXPAND_INDICATOR_TEXT_VIEW: + String expandText = typedArray.getString(R.styleable.ExpandableTextView_expandIndicator); + String collapseText = typedArray.getString(R.styleable.ExpandableTextView_collapseIndicator); + expandIndicatorController = new TextViewExpandController(expandText, collapseText); + break; + default: + throw new IllegalStateException("Must be of enum: ExpandableTextView_expandToggleType, one of EXPAND_INDICATOR_IMAGE_BUTTON or EXPAND_INDICATOR_TEXT_VIEW."); + } + + return expandIndicatorController; + } + class ExpandCollapseAnimation extends Animation { private final View mTargetView; private final int mStartHeight; @@ -362,4 +388,56 @@ public interface OnExpandStateChangeListener { */ void onExpandStateChanged(TextView textView, boolean isExpanded); } + + interface ExpandIndicatorController { + void changeState(boolean collapsed); + + void setView(View toggleView); + } + + static class ImageButtonExpandController implements ExpandIndicatorController { + + private final Drawable mExpandDrawable; + private final Drawable mCollapseDrawable; + + private ImageButton mImageButton; + + public ImageButtonExpandController(Drawable expandDrawable, Drawable collapseDrawable) { + mExpandDrawable = expandDrawable; + mCollapseDrawable = collapseDrawable; + } + + @Override + public void changeState(boolean collapsed) { + mImageButton.setImageDrawable(collapsed ? mExpandDrawable : mCollapseDrawable); + } + + @Override + public void setView(View toggleView) { + mImageButton = (ImageButton) toggleView; + } + } + + static class TextViewExpandController implements ExpandIndicatorController { + + private final String mExpandText; + private final String mCollapseText; + + private TextView mTextView; + + public TextViewExpandController(String expandText, String collapseText) { + mExpandText = expandText; + mCollapseText = collapseText; + } + + @Override + public void changeState(boolean collapsed) { + mTextView.setText(collapsed ? mExpandText : mCollapseText); + } + + @Override + public void setView(View toggleView) { + mTextView = (TextView) toggleView; + } + } } \ No newline at end of file diff --git a/lib/src/main/res/values/attrs.xml b/lib/src/main/res/values/attrs.xml index 7979d55..65b48af 100644 --- a/lib/src/main/res/values/attrs.xml +++ b/lib/src/main/res/values/attrs.xml @@ -4,7 +4,11 @@ - - + + + + + + \ No newline at end of file From 517b2c650d4a39e6043b8b6c6f143d39a156bfbe Mon Sep 17 00:00:00 2001 From: Sallai Gergely Date: Mon, 8 Feb 2016 18:08:26 +0100 Subject: [PATCH 3/5] Enable custom IDs for TextView and Expand / Collapse toggler --- .../expandabletextview/ExpandableTextView.java | 13 +++++++++++-- lib/src/main/res/values/attrs.xml | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java index 1312fb0..aa0e80c 100644 --- a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java +++ b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java @@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.support.annotation.DrawableRes; +import android.support.annotation.IdRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -83,6 +84,12 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList private boolean mAnimating; + @IdRes + private int mExpandableTextId = R.id.expandable_text; + + @IdRes + private int mExpandCollapseToggleId = R.id.expand_collapse; + /* Listener for callback */ private OnExpandStateChangeListener mListener; @@ -259,6 +266,8 @@ private void init(AttributeSet attrs) { mMaxCollapsedLines = typedArray.getInt(R.styleable.ExpandableTextView_maxCollapsedLines, MAX_COLLAPSED_LINES); mAnimationDuration = typedArray.getInt(R.styleable.ExpandableTextView_animDuration, DEFAULT_ANIM_DURATION); mAnimAlphaStart = typedArray.getFloat(R.styleable.ExpandableTextView_animAlphaStart, DEFAULT_ANIM_ALPHA_START); + mExpandableTextId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandableTextId, R.id.expandable_text); + mExpandCollapseToggleId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandCollapseToggleId, R.id.expand_collapse); mExpandIndicatorController = setupExpandToggleController(getContext(), typedArray); @@ -272,9 +281,9 @@ private void init(AttributeSet attrs) { } private void findViews() { - mTv = (TextView) findViewById(R.id.expandable_text); + mTv = (TextView) findViewById(mExpandableTextId); mTv.setOnClickListener(this); - mToggleView = findViewById(R.id.expand_collapse); + mToggleView = findViewById(mExpandCollapseToggleId); mExpandIndicatorController.setView(mToggleView); mExpandIndicatorController.changeState(mCollapsed); mToggleView.setOnClickListener(this); diff --git a/lib/src/main/res/values/attrs.xml b/lib/src/main/res/values/attrs.xml index 65b48af..aebdd8e 100644 --- a/lib/src/main/res/values/attrs.xml +++ b/lib/src/main/res/values/attrs.xml @@ -10,5 +10,7 @@ + + \ No newline at end of file From 122879f50be0c65c0e647b2ececc727f2f06329e Mon Sep 17 00:00:00 2001 From: Sallai Gergely Date: Tue, 9 Feb 2016 15:00:01 +0100 Subject: [PATCH 4/5] Always relayout if the contents have changed. This will correct issues such as when a longer text was expanded and then a shorter one get set on the view, the layout stayed the same height. This resulted in much unused space. --- .../android/expandabletextview/ExpandableTextView.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java index aa0e80c..b5daf94 100644 --- a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java +++ b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java @@ -239,6 +239,9 @@ public void setText(@Nullable CharSequence text) { mRelayout = true; mTv.setText(text); setVisibility(TextUtils.isEmpty(text) ? View.GONE : View.VISIBLE); + clearAnimation(); + getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; + requestLayout(); } public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray collapsedStatus, int position) { @@ -249,8 +252,6 @@ public void setText(@Nullable CharSequence text, @NonNull SparseBooleanArray col mCollapsed = isCollapsed; mExpandIndicatorController.changeState(mCollapsed); setText(text); - getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; - requestLayout(); } @Nullable From 3480e8c917854661aac9d6894b167611ae5cb85d Mon Sep 17 00:00:00 2001 From: Gergely Sallai Date: Sat, 15 Oct 2016 10:45:57 +0200 Subject: [PATCH 5/5] Added possibility to not expand the text on TextView click --- .../android/expandabletextview/ExpandableTextView.java | 9 ++++++++- lib/src/main/res/values/attrs.xml | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java index b5daf94..fb1b867 100644 --- a/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java +++ b/lib/src/main/java/com/ms/square/android/expandabletextview/ExpandableTextView.java @@ -90,6 +90,8 @@ public class ExpandableTextView extends LinearLayout implements View.OnClickList @IdRes private int mExpandCollapseToggleId = R.id.expand_collapse; + private boolean mExpandToggleOnTextClick; + /* Listener for callback */ private OnExpandStateChangeListener mListener; @@ -269,6 +271,7 @@ private void init(AttributeSet attrs) { mAnimAlphaStart = typedArray.getFloat(R.styleable.ExpandableTextView_animAlphaStart, DEFAULT_ANIM_ALPHA_START); mExpandableTextId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandableTextId, R.id.expandable_text); mExpandCollapseToggleId = typedArray.getResourceId(R.styleable.ExpandableTextView_expandCollapseToggleId, R.id.expand_collapse); + mExpandToggleOnTextClick = typedArray.getBoolean(R.styleable.ExpandableTextView_expandToggleOnTextClick, true); mExpandIndicatorController = setupExpandToggleController(getContext(), typedArray); @@ -283,7 +286,11 @@ private void init(AttributeSet attrs) { private void findViews() { mTv = (TextView) findViewById(mExpandableTextId); - mTv.setOnClickListener(this); + if (mExpandToggleOnTextClick) { + mTv.setOnClickListener(this); + } else { + mTv.setOnClickListener(null); + } mToggleView = findViewById(mExpandCollapseToggleId); mExpandIndicatorController.setView(mToggleView); mExpandIndicatorController.changeState(mCollapsed); diff --git a/lib/src/main/res/values/attrs.xml b/lib/src/main/res/values/attrs.xml index aebdd8e..8bcd68d 100644 --- a/lib/src/main/res/values/attrs.xml +++ b/lib/src/main/res/values/attrs.xml @@ -12,5 +12,6 @@ + \ No newline at end of file