左:正常的 ellipsize 效果
右:带 “>>” 后缀的 ellipsize 效果
<com.gdeer.gdtesthub.textView.EllipsizeTextView
android:id="@+id/tv_special"
android:layout_width="58dp"
android:layout_height="wrap_content"
android:text="TextFragment"
android:textColor="#ffffff"
android:maxLines="2"
android:ellipsize="end"/>
public class EllipsizeTextView extends AppCompatTextView {
// 来自 android.text.TextUtils
private static final String ELLIPSIS_NORMAL = "\u2026"; // (…)
public static final String ELLIPSIS_FILLER = "\uFEFF"; // 空白字符
String suffix = ">>";
public EllipsizeTextView(Context context) {
super(context);
}
public EllipsizeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EllipsizeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, type);
Layout layout = getLayout();
if (layout != null) {
// 输入的原始文字
String rawText = String.valueOf(layout.getText());
Log.d("zhangjl", "rawText:" + rawText + " length:" + rawText.length());
if (rawText.contains(ELLIPSIS_NORMAL)) {
// 去除空白字符,TextView 自带的 ellipsize 效果就是将超出长度的字符转为空白字符
String trimText = trimBlankChar(rawText);
Log.d("zhangjl", "trimText:" + trimText + " length:" + trimText.length());
String targetText = trimText;
String resultText = "";
// 去除的字符数
int reduceCount = 1;
while (!resultText.equals(targetText)) {
targetText = rawText.subSequence(0, trimText.length() - reduceCount) + ELLIPSIS_NORMAL + suffix;
Log.d("zhangjl", "targetText:" + targetText + " length:" + targetText.length() +
" reduceCount:" + reduceCount);
super.setText(targetText, type);
layout = getLayout();
resultText = trimBlankChar(String.valueOf(layout.getText()));
Log.d("zhangjl", "resultText:" + resultText + " length:" + resultText.length() +
" reduceCount:" + reduceCount);
reduceCount++;
}
}
}
}
public String trimBlankChar(String rawText) {
int index = rawText.indexOf(ELLIPSIS_FILLER);
String trimText = rawText;
if (index > 0) {
trimText = rawText.substring(0, index);
}
return trimText;
}
}