読者です 読者をやめる 読者になる 読者になる

visible true

技術的なメモを書く

RxAndroidを使ってEditTextで初期の高さを指定しつつ入力に従って動的に高さを調整する

※追記

これでいけました!minLinesというのがあったとは。RxAndroidなんかいらんかったんや!

問題

EditTextで初期の高さをセットしつつ、初期の高さを超える行数になったらそれに追従してEditTextの高さを変えたいがlayoutの設定だけでは出来ない。

以下の例だと初期の高さをセット出来るが、行数を越えても追従して大きくならない。かと言ってlinesを指定しないと初期の高さが1行になる。layout_heightを指定する方法も同様。

<EditText
  android:id="@+id/body_edit"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:lines="5"
  />

こうしたい

f:id:sys1yagi:20150112130958p:plain f:id:sys1yagi:20150112131005p:plain

対応

RxAndroidのViewObservable.text()を使ってEditTextを監視し、行数に応じてsetLines()を呼ぶ。

public static final int MIN_LINES = 5;
//...
ViewObservable.text(bodyEdit, true)
    .doOnNext(new Action1<OnTextChangeEvent>() {
      @Override
      public void call(OnTextChangeEvent event) {
        if (event.view.getLineCount() > MIN_LINES) {
          event.view.setLines(event.view.getLineCount());
        } else {
          event.view.setLines(MIN_LINES);
        }
      }
    })
    .subscribe();

Retrolambda*1でjava8しておけば以下の様に書けて良い。

ViewObservable.text(bodyEdit, true)
  .map(event -> event.view.getLineCount())
  .map(count -> count > MIN_LINES ? count : MIN_LINES)
  .doOnNext(bodyEdit::setLines)
  .subscribe();

まとめ

EditText.addTextChangedListener()でもまぁいいんだけどTextWatcherはメソッド3つあるからねー。RxAndroid便利サイコー