このチュートリアルでは、Android TextInputLayoutが提供する機能に詳しく触れていきます。Android TextInputLayoutは、Material Design Support Libraryに含まれるデザインコンポーネントです。
Android TextInputLayoutはLinearLayoutを拡張しています。TextInputLayoutの主な用途は、EditText(またはその派生クラス)をラップし、浮動ヒントアニメーションを有効にすることです。要点:TextInputLayoutは通常のEditTextではなく、TextInputEditTextをラップすべきです。理由?TextInputEditTextはEditTextのサブクラスであり、TextInputLayoutの子として使用するために設計されています。さらに、EditTextを使用するとEditText added is not a TextInputEditText. Please switch to using that class instead
という警告が表示されます。TextInputLayoutには、浮動ヒントラベルを表示するだけでなく、他にも多くの機能があります。
Android TextInputLayoutの機能
このチュートリアルでカバーするいくつかの機能は次のとおりです:
- 浮動ヒントの有効化/無効化
- 浮動ヒントアニメーションの有効化/無効化
- エラーメッセージの表示
- 文字カウンターの表示
- ユーザーが文字数制限を超えた場合に警告する
- 浮動ヒント、エラーラベル、文字カウンターのテキスト表示をカスタマイズする
- パスワードの可視性トグル
これらの機能を1つずつ見て、Android Studioプロジェクトに実装します。
Android TextInputLayoutの例: プロジェクト構造
これは単一のアクティビティアプリケーションです。レイアウト、アクティビティ、
styles.xml
、colors.xml
ファイル内ですべての作業を行います。まず、以下に示すようにbuild.gradle
ファイル内にデザインサポートライブラリの依存関係を追加します。
compile 'com.android.support:design:25.3.1'
浮動ヒントの有効化/無効化
浮動ヒントは、TextInputLayoutではデフォルトで有効になっています。無効にするには、以下の属性をタグ内に追加する必要があります: app:hintEnabled="false"
。以下のxmlコードはactivity_main.xml
レイアウトからで、3つのEditTextフィールドが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:hint="TextInputEditText" />
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled Default" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintEnabled="false">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Disabled" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
第3のEditTextフィールドでは、浮動ヒントが無効になっています。上記のコードの出力を見てみましょう:
浮動ヒントアニメーションの有効化/無効化
前の機能と同様に、浮動ヒントアニメーションはデフォルトで有効になっています。無効にするには、TextInputLayoutタグ内に次の属性を追加する必要があります。app:hintAnimationEnabled="false"
以下のXMLコードは、activity_main.xml
レイアウトから取得されたもので、いずれかのケースのEditTextフィールドが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled Default" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintAnimationEnabled="false">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Hint Animation Disabled" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
上記のコードの出力は以下の通りです。注目すべき点として、2番目のEditTextフィールドはフォーカスされたときに浮動ヒントをアニメーション化しません。
ヒントTextAppearanceのスタイリング
カスタムtextColor
とtextSize
をヒントに使用するには、次の属性を使用します:app:hintTextAppearance="@style/HintText"
。 HintTextスタイルは、以下に示すようにstyles.xml
内に記述されています
<style name="HintText" parent="TextAppearance.Design.Hint">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/colorPrimary</item>
</style>
以下のxmlコードは、activity_main.xml
レイアウトから取得されたもので、EditTextフィールドがヒントの表示/非表示にかかわらず含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Floating Hint Enabled" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/activity_horizontal_margin"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Custom Hint TextAppearance" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
文字カウンター
文字カウンターは、かなりの数のアプリケーションで使用される機能です(Twitterの文字制限を覚えていますか?)。 app:counterEnabled
をtrueに設定し、app:counterMaxLength
にTextInputLayout内で表示したい最大文字数を設定します。文字カウンターは、デフォルトでEditTextの下に表示されます(右下)。このチュートリアルを書いている間、位置を変更する方法はまだありません。カウンターのスタイリングは、ヒントテキストのスタイリングと似ています。今回はapp:counterTextAppearance
という属性が使用されます。プロジェクトのstyles.xmlファイルには、以下のスタイルが追加されています。
<style name="CounterText" parent="TextAppearance.Design.Counter">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_pink</item>
</style>
以下のxmlコードは、activity_main.xml
レイアウトから取得され、デフォルトの文字カウンターおよびカスタムのものを備えたEditTextフィールドが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Character Counter Limit 10" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Character Counter Custom TextAppearance" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
上記のコードの出力は以下のとおりです。 さて、上記の出力を注意深く観察しましょう。
- 最初のEditTextフィールドは、文字数が超過した場合に、カウンターtextColor、ヒントtextColor、およびインジケーターの色が変わります。
- 二番目のEditTextフィールドも同様ですが、制限を超えた場合にカウンターcustom textColorおよびcustom textSizeも変更されます。
文字数の制限を超えた場合に適用するスタイルを指定するには、次に示すcounterFlow属性を使用する必要があります。
文字数カウンターオーバーフロー
先ほど見たように、文字数が制限を超えると、カウンターテキストはcounterFlowで定義された属性を使用します。これらの属性が存在しない場合は、上記の出力で見たようにデフォルトの属性に従います。次に示すapp:counterOverflowTextAppearance
というパラメータを使用する必要があります。スタイルCounterOverflow
はstyles.xml内に存在します:
<style name="CounterOverFlow" parent="TextAppearance.Design.Counter.Overflow">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_orange</item>
</style>
前のactivity_main.xml
レイアウトに以下のコードスニペットを追加してください。
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="CounterOverflow CustomTextAppearance" />
</android.support.design.widget.TextInputLayout>
エラーラベル
app:errorEnabled
を true に設定すると、EditTextフィールドの下の条件にエラーテキストを表示できます。エラーテキストのスタイルを設定するには、app:errorTextAppearance
属性を使用し、styles.xml
ファイル内に以下のコードを追加します。
<style name="ErrorText" parent="TextAppearance.Design.Error">
<item name="android:textSize">16sp</item>
<item name="android:textColor">@color/my_black</item>
</style>
以下のXMLコードは、activity_main.xml
レイアウトから取得したもので、デフォルトのエラーラベルとカスタムエラーラベルのEditTextフィールドが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:id="@+id/errorInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:errorEnabled="true"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:id="@+id/errorEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Default Error Label" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/customErrorInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:errorEnabled="true"
app:errorTextAppearance="@style/ErrorText"
app:hintTextAppearance="@style/HintText">
<android.support.design.widget.TextInputEditText
android:id="@+id/customErrorEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Custom Error Label" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
エラーテキストを表示するには、MainActivity.java
クラスでTextInputLayoutのインスタンスに対して setError(String)
メソッドを呼び出す必要があります。
package com.journaldev.featuresoftextinputlayout;
import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
public class MainActivity extends AppCompatActivity {
TextInputLayout errorInputLayout, customErrorInputLayout;
TextInputEditText errorEditText, customErrorEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
errorEditText = (TextInputEditText) findViewById(R.id.errorEditText);
errorInputLayout = (TextInputLayout) findViewById(R.id.errorInputLayout);
customErrorEditText = (TextInputEditText) findViewById(R.id.customErrorEditText);
customErrorInputLayout = (TextInputLayout) findViewById(R.id.customErrorInputLayout);
errorEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > errorInputLayout.getCounterMaxLength())
errorInputLayout.setError("Max character length is " + errorInputLayout.getCounterMaxLength());
else
errorInputLayout.setError(null);
}
});
customErrorEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > customErrorInputLayout.getCounterMaxLength())
customErrorInputLayout.setError("Max character length is " + customErrorInputLayout.getCounterMaxLength());
else
customErrorInputLayout.setError(null);
}
});
}
}
上記のコードでは、各TextInputEditTextのインスタンスにTextChangedListener
(TextWatcherを実装)を追加しています。現在の文字数がカウンターの最大制限を超えた場合、エラーラベルを表示します。エラーラベルをクリアするには、setError()
内の値をnullに設定します。上記のコードが提供する出力は: 注意:テキストフィールドのインジケーターはエラーラベルと同じ色を使用します。これはcounterOverflowで設定された色を上書きし、最優先で適用されます。
パスワード表示トグル
app:passwordToggleEnabled
をtrueに設定すると、パスワードを表示/非表示にできます。アイコンの色を変更するにはapp:passwordToggleTint
を使用します。以下のXMLコードはactivity_main.xml
レイアウトから取得され、パスワード表示トグル(デフォルトのアイコンとティント付き)用のEditTextフィールドが含まれています。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password Visibility Toggle"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:counterEnabled="true"
app:counterMaxLength="5"
app:counterOverflowTextAppearance="@style/CounterOverFlow"
app:counterTextAppearance="@style/CounterText"
app:hintTextAppearance="@style/HintText"
app:passwordToggleEnabled="true"
app:passwordToggleTint="@color/my_orange">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password Visibility Toggle Tint"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>
注意:
app:passwordToggleDrawable
を使用して、独自のカスタムアイコンをパスワード表示切り替えに使用できます。これでチュートリアルは終了です。TextInputLayout にある主要な機能をすべてカバーしました。以下のリンクから Android TextInputLayout のサンプルプロジェクト をダウンロードできます。それには上記の各コードスニペットが含まれています。
Android TextInputLayout プロジェクトをダウンロード
参考文献:Android 公式ドキュメント
Source:
https://www.digitalocean.com/community/tutorials/android-textinputlayout-example