package jp.co.industry.omura.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewTreeObserver;
import android.widget.TextView;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MultiLineEllipsizeTextView extends TextView {
private static final String REPLACER = "…";
private static final int MAX_LINES = 3;
private final ViewTreeObserver.OnGlobalLayoutListener mListener;
/**
* コンストラクタ
* @param context
*/
public MultiLineEllipsizeTextView(Context context) {
this(context, null);
}
/**
* コンストラクタ
* @param context
* @param attrs
*/
public MultiLineEllipsizeTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MultiLineEllipsizeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
forceMultiLineEllipsize();
getViewTreeObserver().removeOnGlobalLayoutListener(mListener);
}
};
}
@Override
public void setText(CharSequence text, BufferType type) {
super.setText(text, type);
if (mListener != null) {
this.getViewTreeObserver().addOnGlobalLayoutListener(mListener);
} // mListenerはnullのときもあるため注意。nullを渡すと,渡したときでなくonGlobalLayoutの呼び出し時にオチてしまう
}
/**
* 本来は{@link ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()}で実施したいのだが,RecyclerViewの場合呼ばれないケースがあるためあきらめた。
*/
public void forceMultiLineEllipsize() {
int maxLines = Math.min(MAX_LINES, (int) getHeight() / getLineHeight()); // 現在は3
if (getLineCount() > maxLines) {
int lineEndIndex = getLayout().getLineEnd(maxLines - 1);
if (getText().length() <= lineEndIndex) {
lineEndIndex = getText().length() - 1;
}
String theLastCharOnTheLastIndex = String.valueOf(getText().charAt(lineEndIndex));
boolean isTheLastCharOnTheLastIndexASCII = isAnASCII(theLastCharOnTheLastIndex);
if (isTheLastCharOnTheLastIndexASCII) lineEndIndex -= 1;
final String text2 = getText().subSequence(0, lineEndIndex - REPLACER.length()) + REPLACER;
setText(text2);
} else {
return;
}
}
private static boolean isAnASCII(String str){
Pattern p = Pattern.compile("^[\\p{ASCII}]$");
Matcher m = p.matcher(str);
return m.find();
}
}