Alternative Ways to Handle Events

You've probably noticed that the on... methods of all of the listeners introduced thus far—including onKey—return a boolean value. This is a pattern for listeners that allows them to control subsequent event processing by their caller.

When a Controller event is handed to a widget, the framework code in the widget dispatches it to an appropriate method, depending on its type: onKeyDown, onTouchEvent, etc. These methods, either in View or one its subclasses, implement the widget's behavior. As described earlier, though, the framework first offers the event to an appropriate listener (OnTouchListener, OnKeyListener, etc.) if one exists. The listener's return value determines whether the event is then dispatched to the View methods.

If the listener returns false, the event is dispatched to the View methods as if the handler did not exist. If, on the other hand, a listener returns true, the event is said to have been consumed. The View aborts any further processing for it. The View methods are never called and have no opportunity to process or respond to the event. As far as the View methods are concerned, it is as if the event did not exist.

There are three ways that an event might be processed:

No listener

The event is dispatched to the View methods for normal handling. A widget implementation may, of course, override these methods.

A listener exists and returns true

Listener event handling completely replaces normal widget event handling. The event is never dispatched to the View. A listener exists and returns false

The event is processed by the listener and then by the View. After listener event handling is completed, the event is dispatched to the View for normal handling.

Consider, for instance, what would happen if the key listener from Example 10-10 were added to an EditText widget. Since the onKey method always returns true, the framework will abort any further KeyEvent processing as soon as the method returns. That would prevent the EditText key-handling mechanism from ever seeing the key events, and no text would ever appear in the text box. That is probably not the intended behavior!

If the onKey method instead returns false for some key events, the framework will dispatch those events to the EditText widget for continued processing. The EditText mechanism will see the events, and the associated characters will be appended to the EditText box, as expected. Example 10-11 shows an extension of Example 10-10 that, besides adding new dots to the Model, also filters the characters passed to the hypothetical EditText box. It allows numeric characters to be processed normally but hides everything else.

Example 10-11. Handling keys new OnKeyListener() {

@Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (KeyEvent.ACTION_UP != event.getAction()) { int color = Color.BLUE; switch (keyCode) {

case KeyEvent.KEYCODE_SPACE: color = Color.MAGENTA; break;

case KeyEvent.KEYCODE_ENTER: color = Color.YELLOW;

break; default: ;

makeDot(dotModel, dotView, color);

return (keyCode < KeyEvent.KEYCODE_0) ||(keyCode > KeyEvent.KEYCODE_9);

If your application needs to implement entirely new ways of handling events (in other words, if it is something that cannot be implemented reasonably by augmenting behavior and filtering, using an OnKeyHandler), you will have to understand and override View key event handling. To summarize the process, events are dispatched to the View through the DispatchKeyEvent method. DispatchKeyEvent implements the behavior described previously, offering the event to the onKeyHandler first. If the handler returns false, it offers the event to the View methods implementing the KeyEvent.Callback interface: onKeyDown, onKeyUp, and onKeyMultiple.

0 0

Post a comment