-
-
Save bapspatil/ef32e7da0adcbd453639e9b38493908f to your computer and use it in GitHub Desktop.
A TextView that only click to expand to show full text and click to show shorten text, The ellipsis can be configured too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.mpayme.znap.core.widget; | |
import java.lang.reflect.Field; | |
import android.content.Context; | |
import android.text.SpannableStringBuilder; | |
import android.text.TextUtils; | |
import android.util.AttributeSet; | |
import android.view.View; | |
import android.widget.TextView; | |
import com.mpayme.znap.delib.v3.util.Log; | |
/** | |
* | |
* A TextView that only click to expand to show full text and click to show shorten text, | |
* The ellipsis can be configured too. | |
* | |
* @author Wat Chun Pang Gilbert | |
* | |
*/ | |
public class ExpandableTextView extends TextView { | |
private String mEllipsis = "\u2026\u25BC"; | |
private static final String TAG = ExpandableTextView.class.getSimpleName(); | |
private Boolean mIsExpanded; | |
private Integer mMaxLine; | |
private CharSequence mOriginalText; | |
private static final String sMaximumVarName = "mMaximum"; | |
/** | |
* @param context | |
*/ | |
public ExpandableTextView(Context context) { | |
super(context); | |
init(); | |
} | |
/** | |
* @param context | |
* @param attrs | |
*/ | |
public ExpandableTextView(Context context, AttributeSet attrs) { | |
super(context,attrs); | |
init(); | |
} | |
/** | |
* @param context | |
* @param attrs | |
* @param defStyle | |
*/ | |
public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
init(); | |
} | |
private void init() { | |
expand(); | |
collapse(); | |
super.setOnClickListener(new OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
final ExpandableTextView etv = (ExpandableTextView)v; | |
toggle(etv); | |
} | |
}); | |
} | |
/** | |
* @return is expanded or not | |
*/ | |
protected Boolean isExpanded() { | |
return mIsExpanded; | |
} | |
@Override | |
public void setOnClickListener(OnClickListener l) { | |
Log.e(TAG, "operation is not supported!"); | |
} | |
/** | |
* Toggle if it is expanded or not | |
*/ | |
public final void toggle() { | |
toggle(this); | |
} | |
private final void toggle(ExpandableTextView etv) { | |
if (etv.isExpanded()) { | |
Log.w(TAG, TAG + " is collapsed."); | |
etv.collapse(); | |
} else { | |
Log.w(TAG, TAG + " is expanded."); | |
etv.expand(); | |
} | |
} | |
public void collapse() { | |
mIsExpanded = false; | |
setMaxLines(mMaxLine); | |
postInvalidate(); | |
//The actual change is in onMeasure | |
} | |
public void expand() { | |
mIsExpanded = true; | |
if (mMaxLine == null) { | |
storeMaxLine(); | |
} | |
setEllipsize(null); | |
setMaxLines(Integer.MAX_VALUE); | |
setText(mOriginalText); | |
postInvalidate(); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
if (!mIsExpanded && null != mOriginalText) { | |
final String sTruncatedText = TextUtils.ellipsize(mOriginalText.toString().replace('\n', ' ').replace('\t', ' '), getPaint(), | |
(float) (getRight() - getLeft() - getCompoundPaddingLeft() - getCompoundPaddingRight() - getPaint().measureText(mEllipsis)) * mMaxLine, | |
TextUtils.TruncateAt.END).toString(); | |
if (sTruncatedText.length() > 2 && !sTruncatedText.equals(mOriginalText)) { | |
SpannableStringBuilder ssb = new SpannableStringBuilder(sTruncatedText.trim(), 0, sTruncatedText.length() - 2); | |
ssb.append(mEllipsis); | |
setText(ssb.toString()); | |
} | |
} | |
} | |
/** | |
* Extract private maxLine from super class | |
*/ | |
private void storeMaxLine() { | |
Field f; | |
try { | |
f = getClass().getSuperclass().getDeclaredField(sMaximumVarName); | |
f.setAccessible(true); | |
mMaxLine = f.getInt(this); | |
f.setAccessible(false); | |
} catch (SecurityException e) { | |
//impossible | |
Log.e(TAG, e.getMessage()); | |
} catch (NoSuchFieldException e) { | |
//impossible | |
Log.e(TAG, e.getMessage()); | |
} catch (IllegalArgumentException e) { | |
//impossible | |
Log.e(TAG, e.getMessage()); | |
} catch (IllegalAccessException e) { | |
//impossible | |
Log.e(TAG, e.getMessage()); | |
} | |
} | |
/** | |
* Reset the text | |
* @param text | |
*/ | |
public void resetText(CharSequence text) { | |
mOriginalText = null; | |
setText(text); | |
} | |
@Override | |
public void setText(CharSequence text, BufferType type) { | |
super.setText(text, type); | |
if (mOriginalText == null) { | |
mOriginalText = text; | |
} | |
} | |
/** | |
* Set the ellipsis of the TextView | |
* @param ellipsis | |
*/ | |
public void setEllipsis(final String ellipsis) { | |
this.mEllipsis = ellipsis; | |
} | |
/** | |
* @return the ellipsis | |
*/ | |
public String getEllipsis() { | |
return this.mEllipsis; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment