リア充爆発日記

You don't even know what ria-ju really is.

DialogのEditor、名付けてDialogEditor

EditTextをそのまま使うと、入力時にソフトウェアキーボードでエディタエリアが隠れたり、入力文字数のカウント表示をしようと思っても場所がなかったりといろいろ困ることが多い。で、そういう場合はダイアログ形式にして対応している人が多かったのでぼくもそうすることにしてみた。

dialog_editor.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
        >

    <EditText android:id="@+id/dialog_editor_edit_text"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:gravity="top|left"
              android:hint="@string/common_hint"
            />

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:orientation="horizontal"
                  android:gravity="right"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
            >
        <TextView android:id="@+id/dialog_editor_counter_numerator"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:paddingRight="10dp"
                  android:text="@string/none"
                />
        <TextView android:id="@+id/dialog_editor_counter_delimiter"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:paddingRight="10dp"
                  android:text="@string/counter_delimiter"
                />
        <TextView android:id="@+id/dialog_editor_counter_denominator"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:paddingRight="10dp"
                  android:text="@string/none"
                />
    </LinearLayout>

    <Button android:id="@+id/dialog_editor_ok_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/ok"
            />

DialogEditor.java

import android.app.Dialog;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class DialogEditor  {
    private static final String TAG = DialogEditor.class.getSimpleName();

    private final Dialog mDialog;
    private EditText mBoundEditText;
    private TextView mNumerator;
    private TextView mDenominator;
    private EditText mEditText;
    private Button mOKButton;
    private int mLimit;

    public DialogEditor(Context context, EditText editText, int limit) {
        this.mDialog = new Dialog(context);
        this.mBoundEditText = editText;
        this.mLimit = limit;
    }

    public void show() {
        mDialog.setContentView(R.layout.dialog_editor);


        mNumerator = (TextView) mDialog.findViewById(R.id.dialog_editor_counter_numerator);
        mNumerator.setText(String.valueOf(mBoundEditText.getText().length()));
        mDenominator = (TextView) mDialog.findViewById(R.id.dialog_editor_counter_denominator);
        mDenominator.setText(String.valueOf(mLimit));

        mEditText = (EditText) mDialog.findViewById(R.id.dialog_editor_edit_text);
        mEditText.setText(mBoundEditText.getText().toString());

        mOKButton = (Button)mDialog.findViewById(R.id.dialog_editor_ok_btn);

        mEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
                // nothing to do.
            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
                if (charSequence.length() > mLimit) {
                    mNumerator.setTextColor(mDialog.getContext().getResources().getColor(R.color.alert_red));
                    mOKButton.setEnabled(false);

                } else {
                    mNumerator.setTextColor(mDialog.getContext().getResources().getColor(android.R.color.black));
                    mOKButton.setEnabled(true);
                }
                mNumerator.setText(String.valueOf(charSequence.length()));
            }

            @Override
            public void afterTextChanged(Editable editable) {
                // nothing to do.
            }
        });

        showSoftwareKeyboard(mEditText);

        mOKButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mBoundEditText.setText(mEditText.getText().toString());

                mDialog.dismiss();

            }
        });


        mDialog.setTitle(mBoundEditText.getHint().toString());

        mDialog.show();

        adjustWindowSize();
    }

    private void showSoftwareKeyboard(EditText editText) {
        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean b) {
                if (b) {
                    mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
                }
            }
        });
    }

    private void adjustWindowSize() {
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
        layoutParams.copyFrom(mDialog.getWindow().getAttributes());
        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;

        mDialog.getWindow().setAttributes(layoutParams);
    }
}

タイトルにはもともとのEditTextのhintが入る。指定したlimitより入力文字数が多くなると、入力文字数が赤くなって、OKボタンが押せなくなる。
まだ整理しきれてないのでstring.xmlの要素とかちょこちょこ必要だけどだいたいこんな感じ。


入力予測欄があるときとないときで画面がにょいんにょいんするのがヤだからそのうち直そう。
それにしても、コレ、再発明のニオイがプンプンするな。。。