hackugyo
2/2/2016 - 6:43 AM

http://qiita.com/hackugyo/items/e23ecfda14bdfc672e7c 改善

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();
    }

}
    public class FontFitViewHolder extends RecyclerView.ViewHolder {
        private final FontFitViewHolder self = this;
        private Handler mHandler;

        public BandCheckViewHolder(View v, int height) {
            super(v);
            mCardView = (CardView)itemView;

            mTextView = (MultiLineEllipsizeTextView) v.findViewById(R.id.viewholder_fontfit_card);
        }

        public void setText(String text) {
            mTextView.setText(text);
            if (mHandler == null) mHandler = new Handler(itemView.getContext().getMainLooper());
            mHandler.post(new Runnable() {
              @Override
              public void run() {
                mTextView.forceMultiLineEllipsize();
              }
            }
        }
    }