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

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Floating Labels for EditTextを実装してみた

今回のエンジニアブログを担当する佐藤です。

前回FAB(Floating Action Button)に引き続き、TextInputLayoutをつかったFloating Labels for EditTextを実装したいと思います。

【Floating Labels for EditText】
Floating Labels for EditTextは、TextInputLayoutを使用したMaterial DesignのTextEditです。
TextInputLayoutはDesign Support Libraryに追加された機能です。

TextInputLayoutを使用すると、入力フォーム選択時にラベルがフォームの上へ移動するアニメーションをするようになります。
Screenshot_2015-10-09-19-53-13

実装はとても簡単でした。
今回もDesign Support Library使用するので、build.gradleに追記していきます。

build.gradle

dependencies {  
    compile 'com.android.support:design:22.2.0'  
}  

レイアウトは以下のようになっています。
activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:paddingLeft="@dimen/activity_horizontal_margin"  
    android:paddingRight="@dimen/activity_horizontal_margin"  
    android:paddingTop="@dimen/activity_vertical_margin"  
    android:paddingBottom="@dimen/activity_vertical_margin"  
    android:orientation="vertical"  
    tools:context=".MainActivity">  
  
    <android.support.design.widget.TextInputLayout  
        android:id="@+id/input_name"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content">  
  
        <EditText  
            android:id="@+id/name"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:singleLine="true"  
            android:hint="@string/name" />  
    </android.support.design.widget.TextInputLayout>  
  
    <android.support.design.widget.TextInputLayout  
        android:id="@+id/input_password"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content">  
        <EditText  
            android:id="@+id/password"  
            android:layout_width="match_parent"  
            android:layout_height="wrap_content"  
            android:inputType="textPassword"  
            android:hint="@string/password" />  
  
    </android.support.design.widget.TextInputLayout>  
</LinearLayout>  
  

string.xml

<?xml version="1.0" encoding="utf-8"?>  
<resources>  
    <string name="app_name">FloationgLabelTextEdit</string>  
    <string name="name">名前</string>  
    <string name="password">パスワード</string>  
</resources>  

android:hintで設定した文字が入力フォームに表示されています。

また、TextInputLayoutはsetError()でエラーメッセージを表示することができます。
MainActivity.java

public class MainActivity extends Activity{  
    TextInputLayout inputLayoutName;  
    TextInputLayout inputLayoutPassword;  
    EditText textName;  
    EditText textPassword;  
    Button btnOk;  
    HashMap<String, Boolean> errorCheck;  
  
    // パスワードの最小文字数  
    final int PASS_MIN = 6;  
    // パスワードの最大文字数  
    final int PASS_MAX = 12;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        errorCheck = new HashMap<String, Boolean>();  
        errorCheck.put("name", false);  
        errorCheck.put("password", false);  
  
        inputLayoutName = (TextInputLayout) findViewById(R.id.input_name);  
        inputLayoutPassword = (TextInputLayout) findViewById(R.id.input_password);  
  
        textName = (EditText) findViewById(R.id.name);  
        textPassword = (EditText) findViewById(R.id.password);  
  
        // 入力中のチェック  
        textName.addTextChangedListener(new EditTextWatcher(textName));  
        textPassword.addTextChangedListener(new EditTextWatcher(textPassword));  
  
        btnOk = (Button) findViewById(R.id.btn_ok);  
        btnOk.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View view) {  
                // 名前の入力とパスワードの入力に不備がなければToastを表示  
                if(checkNameInput() || checkPassInput()) {  
                    Toast.makeText(view.getContext(), view.getContext().getText(R.string.input_success), Toast.LENGTH_SHORT).show();  
                }else{  
                    updateButton();  
                }  
            }  
        });  
    }  
  
    /**  
     * 「名前」の入力チェック  
     */  
    private boolean checkNameInput(){  
        // 空白ならエラー表示  
        if(textName.getText().toString().trim().isEmpty()){  
            inputLayoutName.setError(getString(R.string.error_name_empty));  
            return false;  
        }  
  
        inputLayoutName.setErrorEnabled(false);  
        return true;  
    }  
  
    /**  
     * 「パスワード」の入力チェック  
     */  
    private  boolean checkPassInput(){  
        String password = textPassword.getText().toString().trim();  
        // 空白ならエラー表示  
        if(password.length() == 0){  
            inputLayoutPassword.setError(getString(R.string.error_pass_empty));  
            return false;  
        }  
  
        // 最小文字数以下ならエラー表示  
        if(password.length() < PASS_MIN){  
            inputLayoutPassword.setError(getString(R.string.error_pass_min, PASS_MIN));  
            return false;  
        }  
          
        // 最大文字数を超えていたらエラー  
        if(password.length() > PASS_MAX){  
            inputLayoutPassword.setError(getString(R.string.error_pass_max, PASS_MAX));  
            return false;  
        }  
  
        inputLayoutPassword.setErrorEnabled(false);  
        return true;  
    }  
  
    /**  
     * OKボタンの状態を更新  
     */  
    private void updateButton(){  
        // 入力内容に不備があれば押せないようにする  
        if(!errorCheck.get("name") || !errorCheck.get("password")){  
            btnOk.setEnabled(false);  
        }else{  
            btnOk.setEnabled(true);  
        }  
    }  
  
    /**  
     * 入力フォームの状態を取得する  
     */  
    private class EditTextWatcher implements TextWatcher {  
        View v;  
  
        public EditTextWatcher(EditText editText) {  
            v = editText;  
        }  
  
        @Override  
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {  
  
        }  
  
        @Override  
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {  
  
        }  
  
        @Override  
        public void afterTextChanged(Editable editable) {  
            // 文字を入力時に入力内容をチェックしエラーの表示やボタンの状態を更新する  
            switch (v.getId()) {  
                case R.id.name:  
                    errorCheck.put("name", checkNameInput());  
                    break;  
                case R.id.password:  
                    errorCheck.put("password", checkPassInput());  
                    break;  
            }  
            updateButton();  
        }  
    }  
}  

実機で確認するとこうなりました!

◆起動時
Screenshot_2015-10-12-19-34-27

◆空白でOK押下時
Screenshot_2015-10-12-19-34-36

◆パスワード入力中エラーチェック
Screenshot_2015-10-12-19-34-59

◆エラーなし
Screenshot_2015-10-12-19-35-05

動きが細かいですが、このような細かい動きでもMaterialDesignらしいアプリケーションになるので積極的に実装していきたいです!