まずは動作確認
↓な感じのテキストフィールドの実装方法を紹介します
実装方法
TextInputLayoutを使う
このいい感じなテキストフィールドを実現するためには、Design Support LibraryのTextInputLayoutを使います。
<android.support.design.widget.TextInputLayout
android:id="@+id/userNameTextImaputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:errorEnabled="true"
app:counterEnabled="true"
app:counterMaxLength="10"
app:hintEnabled="true"
app:hintAnimationEnabled="true"
android:layout_marginTop="67dp">
</android.support.design.widget.TextInputLayout>
app:hintAnimationEnabled="true"
でplaceholderのアニメーションを有効化しています。このアニメーションはマテリアルデザインに則っているため、自分でカスタマイズする必要なく、マテリアルデザインなアニメーションを実現できます。
ちなみにfalseにするとアニメーションしなくなります。
他にもapp: counterEnabled ="true"
で右下の文字数カウンター表示を有効化しています。
子ViewにTextInputEditTextを配置
次に実際に入力するためのView、TextInputEditTextをTextInputLayoutの中にを入れます。
<android.support.design.widget.TextInputLayout
android:id="@+id/userNameTextImaputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:errorEnabled="true"
app:counterEnabled="true"
app:counterMaxLength="10"
app:hintEnabled="true"
app:hintAnimationEnabled="true"
android:layout_marginTop="67dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/userNameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ユーザー名"
android:imeOptions="actionSend"
android:inputType="text"
android:maxLines="1"
android:textSize="20sp"/>
</android.support.design.widget.TextInputLayout>
縦画面のみ対応の場合、子Viewは普通のEditTextでも大丈夫なのですが、横画面にした時にバグがあるため、横も対応する場合は TextInputEditText
を指定します。
以上でいい感じのテキストフィールドが実現できます。
エラー文の表示もしたい場合はコードでやることになります。
エラー文表示
binding.userNameEditText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s!!.length > binding.userNameTextImaputLayout.counterMaxLength) {
binding.userNameTextImaputLayout.error = "ユーザー名は10文字以内で入力してください"
} else {
binding.userNameTextImaputLayout.error = null
}
}
})
TextInputEditTextの入力イベントをTextWatcherで監視し、最大文字数を超えたらTextInputLayoutのerror
にエラー文を設定します。最大文字数を超えていなければerror
にnullを設定し、エラー文字を消します。
この最大文字数を超えたら判定は自分で行うことになります。
if (s!!.length > binding.userNameTextImaputLayout.counterMaxLength) {
この部分ですね。
これでエラー文の表示もできるようになりました。
最後に
簡単にいい感じのテキストフィールドを実装することができました。
こんな感じのテキストフィールドを欲しくなることがあると思うので、そんな時は自作するのではなく、これ使うと良いと思います
コードはこちらあります
※ちなみに...
親のレイアウトにConstraintLayoutを使っています
Databindingを使用しています
コードはkotlinで書いています