2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AndroidのEditTextにsetOnKeyListenerを使う時にEditTextの内容を消せなくなる問題

Last updated at Posted at 2018-01-14

背景

アプリのSearchBarにEditTextを設置して、EditTextに文字をに入力して、keyboardのEnter keyを押して検索処理を行う。EditTextにキーボード操作をさせる時には、ViewクラスのOnKeyListenerインタフェースを実装するmOnKeyListener変数のonKeyメソードメソードが実行される。
だからEditTextにキーボード操作をさせる時に何が実装したい時には、自分からViewクラスのmOnKeyListenerを定義する必要がある。ここではViewクラスのsetOnKeyListenerメソードを使って、ViewクラスのmOnKeyListener変数を定義する。

FragmentListenerActivity.java

public class FragmentListenerActivity extends AppCompatActivity {


    private ArrayList<String> mList = null;
    private Context mContext = null;
    private ListView mListView = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_listener);

        final EditText mEditText = (EditText) findViewById(R.id.mEdit);

        mEditText.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if ((keyCode == KeyEvent.KEYCODE_ENTER) ||
                            (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
                            String res = mEditText.getText().toString();
                            ((TextView)findViewById(R.id.mText)).setText(res);
                    }
                }
                return true;
            }
        });
    }
}

activity_fragment_listener.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="com.example.syoui.imagetab.foundation.fragment.FragmentListenerActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:id="@+id/mEdit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/mText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</android.support.constraint.ConstraintLayout>

SVID_20180114_222813(2).gif
図1

図1のように,キーボードのEnterキーを押したら,またdeleteキーを消したら,意外にEditTextの内容が消えなくなる問題だ.社内の先輩の方聞いたらFragmentListenerActivity.javaを以下のように変えたら,もう消せるようになる.

        mEditText.setOnKeyListener(new View.OnKeyListener() {
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if ((keyCode == KeyEvent.KEYCODE_ENTER) ||
                            (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
                            String res = mEditText.getText().toString();
                            ((TextView)findViewById(R.id.mText)).setText(res);
                    }
                }
                //return true;
                return false;
            }
        });

SVID_20180114_225050.gif
図2

図2のように,Enterキーを押して入力した内容を確定したら,deleteキーを押したらEditTextの内容もどんどん消していった.
ソースコードで編集した内容は,ただ一行たけで
onKeyの実装の最後には
return true;ではなく 
return false;です!

原因としては,return trueしたら,このEditTextのonKeyの実行はもう他のところから呼べなくなる.onKeyのメソードを呼ぶのはここではなく,deleteキーを押すときには他のどこかにもこのonKeyメソードも呼んでいるから,ここでのonKey処理が終わったら,return falseで,次の処理に回すべきだ.
[アンドロイドの公式説明](https://developer.android.com/reference/android/view/View.OnKeyListener.html)

アンドロイドの公式ではそういった,

スクリーンショット 2018-01-14 23.13.58.png
図3

Interface definition for a callback to be invoked when a hardware key event is dispatched to this view. The callback will be invoked before the key event is given to the view. This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener.

つまり,hardwareキーボードでこのviewに対して操作するときにこのonKeyメソードの内容を実行する.我々は定義したonKeyのところもちろん実行するが,他のところの実行するだろう.
もっと見たら,Return値の説明もあります.

スクリーンショット 2018-01-14 23.15.48.png
図4

ということで,return true;の場合にはこのlistenerはこのeventを消化する.つまり,return true;の場ありには,hardwareキーボードがこのviewに対してなんか操作する時には,onKeyを実行しなくなる.なるほどかな,

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?