[Android] TextViewで変な所に改行が入るのを防ぐ

スポンサーリンク

はじめに

TextViewに長文を入れると変な所に改行が入ったりすることがある。

調べてみると、英語圏では単語単位で改行を入れるのが一般的らしい。

改行について

日本語で変な所に改行入れられちゃうと文章が読みにくくなったりするので、対処方法。

結構面倒くさい。諸々の考慮は全くしていない(ぉぃ

実装

InputFilterを作成する

このInputFilterクラスでTextViewの幅を取得し、文字幅がView幅より大きくなりそうだったら文字に改行文字を入れる。

自前で改行位置を決定できるので、特定の文字列が来たら改行するとかは結構簡単にできるようになる。

//
public class WrapTextViewFilter implements InputFilter {
    private final TextView view;
 
    public WrapTextViewFilter(TextView view) {
      this.view = view;
   }
 
 @Override
 public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
       TextPaint paint = view.getPaint();
       int w = view.getWidth();
       int wpl = view.getCompoundPaddingLeft();
       int wpr = view.getCompoundPaddingRight();
       int width = w - wpl - wpr;
 
      SpannableStringBuilder result = new SpannableStringBuilder();
       for (int index = start; index < end; index++) {
 
          if (Layout.getDesiredWidth(source, start, index + 1, paint) > width) {
               result.append(source.subSequence(start, index));
                result.append("\n");
                start = index;
 
          } else if (source.charAt(index) == '\n') {
              result.append(source.subSequence(start, index));
                start = index;
          }
       }
 
       if (start < end) {
           result.append(source.subSequence(start, end));
      }
       return result;
  }
}

カスタムTextViewを作成

InputFilterを書き換え用のTextView。

//
public class WrapTextView  extends TextView{
 
    private CharSequence mOrgText = "";
    private BufferType mOrgBufferType = BufferType.NORMAL;
 
    public WrapTextView(Context context) {
        super(context);
        setFilters(new InputFilter[] { new WrapTextViewFilter(this) });
    }
 
    public WrapTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setFilters(new InputFilter[] { new WrapTextViewFilter(this) });
    }
 
    public WrapTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setFilters(new InputFilter[] { new WrapTextViewFilter(this) });
    }
 
    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        setText(mOrgText, mOrgBufferType);
    }
 
    @Override
    public void setText(CharSequence text, BufferType type) {
        mOrgText = text;
        mOrgBufferType = type;
        super.setText(text, type);
    }
 
    @Override
    public CharSequence getText() {
        return mOrgText;
    }
 
    @Override
    public int length() {
        return mOrgText.length();
    }
}

結果

画像が荒くて申し訳ないorz

そのままのほうは今回は3行目と5行目に変な所に改行が入ってるけど、DrawTextの方は改行が入ってない。

https://amzn.to/2VHpxPz
タイトルとURLをコピーしました