The document discusses methods for handling focus changes between multiple EditText fields without hiding the soft keyboard. It recommends using a combination of SingleLine, NextFocus, and OnEditorActionListener. SingleLine prevents line breaks, NextFocus specifies the next field, and OnEditorActionListener handles focus changes on editor actions like IME_ACTION_NEXT. It notes the NextFocus attribute and actionId values depend on the target view's position. This allows focus to move smoothly between fields without dismissing the soft keyboard.
9. OnKeyListener
TextView.java
KeyDown
private int doKeyDown(int keyCode, KeyEvent event, KeyEvent otherEvent) {
if (!isEnabled()) {
return 0;
}
!
!
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = true;
if (event.hasNoModifiers()) {
// When mInputContentType is set, we know that we are
// running in a "modern" cupcake environment, so don't need
// to worry about the application trying to capture
// enter key events.
if (mInputContentType != null) {
// If there is an action listener, given them a
// chance to consume the event.
if (mInputContentType.onEditorActionListener != null &&
mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
mInputContentType.enterDown = true;
// We are consuming the enter key for them.
return -1;
}
}
//
//
//
if
}
}
break;
If our editor should move focus when enter is pressed, or
this is a generated event from an IME action button, then
don't let it be inserted into the text.
((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
|| shouldAdvanceFocusOnEnter()) {
if (mOnClickListener != null) {
return 0;
}
return -1;
10. OnKeyListener
TextView.java
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (!isEnabled()) {
return super.onKeyUp(keyCode, event);
}
!
!
KeyUp
switch (keyCode) {
~~
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = false;
if (event.hasNoModifiers()) {
if (mInputContentType != null
&& mInputContentType.onEditorActionListener != null
&& mInputContentType.enterDown) {
mInputContentType.enterDown = false;
if (mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
return true;
}
}
if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
|| shouldAdvanceFocusOnEnter()) {
/*
* If there is a click listener, just call through to
* super, which will invoke it.
*
* If there isn't a click listener, try to advance focus,
* but still call through to super, which will reset the
* pressed state and longpress state. (It will also
* call performClick(), but that won't do anything in
* this case.)
*/
~~
}
return super.onKeyUp(keyCode, event);
onKeyListenerでは
EditorActionが2回呼ばれる
Overrideすると、OnEditorAction
が呼ばれない
}
break;
11. OnKeyListener
TextView.java
KeyDown
private int doKeyDown(int keyCode, KeyEvent event, KeyEvent otherEvent) {
if (!isEnabled()) {
return 0;
}
!
!
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = true;
if (event.hasNoModifiers()) {
// When mInputContentType is set, we know that we are
// running in a "modern" cupcake environment, so don't need
// to worry about the application trying to capture
// enter key events.
if (mInputContentType != null) {
// If there is an action listener, given them a
// chance to consume the event.
if (mInputContentType.onEditorActionListener != null &&
mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
mInputContentType.enterDown = true;
// We are consuming the enter key for them.
return -1;
}
}
//
//
//
if
}
}
break;
If our editor should move focus when enter is pressed, or
this is a generated event from an IME action button, then
don't let it be inserted into the text.
((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
|| shouldAdvanceFocusOnEnter()) {
if (mOnClickListener != null) {
return 0;
}
return -1;
13. OnKeyListener
TextView.java
KeyDown
private int doKeyDown(int keyCode, KeyEvent event, KeyEvent otherEvent) {
if (!isEnabled()) {
return 0;
}
!
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
mEnterKeyIsDown = true;
if (event.hasNoModifiers()) {
// When mInputContentType is set, we know that we are
// running in a "modern" cupcake environment, so don't need
// to worry about the application trying to capture
// enter key events.
if (mInputContentType != null) {
// If there is an action listener, given them a
// chance to consume the event.
if (mInputContentType.onEditorActionListener != null &&
mInputContentType.onEditorActionListener.onEditorAction(
this, EditorInfo.IME_NULL, event)) {
mInputContentType.enterDown = true;
// We are consuming the enter key for them.
return -1;
}
}
enterがreturnされるので
eventがnullになる
!
//
//
//
if
}
}
break;
If our editor should move focus when enter is pressed, or
this is a generated event from an IME action button, then
don't let it be inserted into the text.
((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0
|| shouldAdvanceFocusOnEnter()) {
if (mOnClickListener != null) {
return 0;
}
return -1;
14. TextView.java
OnEditorAction
public void onEditorAction(int actionCode) {
final InputContentType ict = mInputContentType;
if (ict != null) {
if (ict.onEditorActionListener != null) {
if (ict.onEditorActionListener.onEditorAction(this,
actionCode, null)) {
return;
}
}
Focus移動の
メソッドを呼ぶ
//
//
//
//
//
if
!
This is the handling for some default action.
Note that for backwards compatibility we don't do this
default handling if explicit ime options have not been given,
instead turning this into the normal enter key codes that an
app may be expecting.
(actionCode == EditorInfo.IME_ACTION_NEXT) {
View v = focusSearch(FOCUS_FORWARD);
if (v != null) {
if (!v.requestFocus(FOCUS_FORWARD)) {
throw new IllegalStateException("focus search returned a view " +
"that wasn't able to take focus!");
}
}
return;
} else if (actionCode == EditorInfo.IME_ACTION_PREVIOUS) {
View v = focusSearch(FOCUS_BACKWARD);
if (v != null) {
if (!v.requestFocus(FOCUS_BACKWARD)) {
throw new IllegalStateException("focus search returned a view " +
"that wasn't able to take focus!");
}
}
return;
OnEditorActionを
!
呼ぶことでFocus移動
} else if (actionCode == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null && imm.isActive(this)) {
imm.hideSoftInputFromWindow(getWindowToken(), 0);
}
clearFocus();
return;
}
}