AndroidのOnKeyListenerは2度呼ばれる
今週からAndroidのネイティブアプリを作ってます。Android歴は3日目です。
XMLベースで画面を作るのは滅茶苦茶WPFに似ているので全く違和感なく入れました。イベントハンドラの実装も簡単だし。Activityという単位で画面構成がされること、そいつ自体がスタック構造になっており、デフォルトではActivityを呼ぶ度に新しいインスタンスが作られる。ゾンビActivityがじゃんじゃん生成されることに気をつけたい。
GUIアプリってUI回りでメモリリークしない為にどうするんだっけってのが実装の肝だと感じます。
で、テキストフィールド(EditText)のEnterのキーイベントを拾おうと思ってこんなコード書きました。
final EditText textView = (EditText)view.findViewById(R.id.textView1); textView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { if(i == KeyEvent.KEYCODE_ENTER){ System.out.println("text is "+ textView.getText()); return true; } return false; } });
このコードを実行すると、System.out.printlnが2回も呼ばれてしまいます。その理由は俺たちのStackOverflowに書いてありました。
OnKey is fire twice: the first time for key down, and the second time for key up, so you have to filter
android - Why is onKey() called twice? - Stack Overflow
Windows系だとKeyDown、KeyPress、KeyUpと細かくイベントがわかれているんですけど、なんかAndroidはOnKeyで全部まとめちゃった仕様なんだって。なので、1度しか発生させたくない場合は、以下の様にフィルターをはさもう。
final EditText textView = (EditText)view.findViewById(R.id.textView1); textView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { //ここ if (event.getAction()!=KeyEvent.ACTION_DOWN) return false; if(i == KeyEvent.KEYCODE_ENTER){ System.out.println("text is "+ textView.getText()); return true; } return false; } });