问题
Here is my code:
public class CaptureENTER extends Activity implements OnKeyListener{
/* on create and other stuff in here*/
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
Toast.makeText(LiVoiceActivity.this,
"YOU CLICKED ENTER KEY",
Toast.LENGTH_LONG).show();
}
return false;
}
I don't know what is going on, but when I press the ENTER key in my keyboard (I am using the Android emulator), the event is not activated.
What am I missing?
回答1:
Returning true
is not the issue.
You're failing because you must set the listener to a View
, not just the Activity
.
edited for clarification:
The return value of the listener is not meant to be understood as a signal that the event will or will not be called. And it couldn't anyway, since the return
clause is only called after your Toast
is shown.
It's a signal to the system that further action is needed (return false
) or that the method handled the event fully and properly (return true
). That's why the documentation says in these words:
Returns
True if the listener has consumed the event, false otherwise.
There's a difference between:
- Implementing the
View.OnKeyListener
interface
in yourActivity
class.
That allows your Activity
to implement the functionality provided by the interface in your class, i.e., to declare to the world that your Activity
knows how to handle that kind of event.
Please pay attention to the fact that I said "declare". Just because you declared that you know how to handle a task doesn't mean people will give that task to you, nor does it mean that you can generate such tasks by yourself. It's a good metaphor for the implements
keyword in my opinion. Here the Activity
"asks for a task".
Metaphors aside, technically, the Activity
is defining a way to handle that event, but it can't generate that kind of event by itself.
- setting the
View
callbacks to yourActivity
implementation
Using that, a View
binds to a listener (which happens to be your Activity
), promising to notify it whenever the event happens.
It "contracts" with your Activity
to receive an input (the user presses the ENTER key while the View
is in focus) and notifies the Activity
. And since the Activity
previously declared that it's capable of performing that, BOTH parties can execute the contract as previously agreed (see previous item).
Metaphors aside again, technically, here the Activity
is registered by the View
to be notified later when the View
trigger the event. The Activity
declares how, but the View
knows when.
Conclusion:
This is just a metaphor for interface
s (at least in this case). It may look complicated, but it's crystal clear when you think of it as a two-party agreement. If you need a better, technical, explanation, I suggest reading about interface
s.
Answer to the new comment question:
Hello David and everyone else. Really I can't set a listener to the whole Activity?
Not in that way. You need to override dispatchKeyEvent
. An example:
@Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
Toast.makeText(UITestsActivity.this,
"YOU CLICKED ENTER KEY",
Toast.LENGTH_LONG).show();
return true;
}
return super.dispatchKeyEvent(e);
};
回答2:
Try this:
public class CaptureENTER extends Activity implements OnKeyListener{
/* on create and other stuff in here*/
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
Toast.makeText(LiVoiceActivity.this,
"YOU CLICKED ENTER KEY",
Toast.LENGTH_LONG).show();
return true;
}
return false;
}
EDIT: David is CORRECT!!
Returning true is not the issue.
You're failing because you must set the listener to a View, not just the Activity.
来源:https://stackoverflow.com/questions/11237731/listen-to-enter-key-in-android