エンジニア

Floating Labels for EditTextを実装してみた

投稿日:2015年10月13日 更新日:

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

前回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らしいアプリケーションになるので積極的に実装していきたいです!

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-,

© WonderPlanet Inc.