null keyevent and actionid = 0 in onEditorAction() (Jelly Bean / Nexus 7)

后端 未结 6 739
醉梦人生
醉梦人生 2020-12-03 10:18

I have an edit text which functions as a search box in my application. In Jelly Bean on my Nexus 7 when I type something into the text box which I am listening on and hit en

相关标签:
6条回答
  • 2020-12-03 10:43

    Ended up adding in a null check for KeyEvent. Thanks to commonsware for pointing out this happens on 3.0+. Seems more like a workaround then a solution, but it works.

    // Search field logic.
    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        Log.d(TAG, "onEditorAction");
        if (event != null && event.getAction() != KeyEvent.ACTION_DOWN) {
            return false;
        } else if (actionId == EditorInfo.IME_ACTION_SEARCH
            || event == null
            || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
                  .....Do some stuff();
        }
    }
    
    0 讨论(0)
  • 2020-12-03 10:55

    You dont discover the truth, if you customize return key. You need both set imeActionLabel and imeActionId in your layout. Such as:

    imeActionLabel="xxxx"
    imeActionId = "6"
    

    In your java code:

    @Override
    public boolean onEditorAction(TextView v, int actionId,  KeyEvent event) {
    if (actionId == EditorInfo.IME_ACTION_DONE) {
         doSomeThing();
         return true;
       }
    
        return false;
    }
    

    It will work fine.

    0 讨论(0)
  • 2020-12-03 10:55

    The action id is set to 0 by default for any enter event.

    From the Android documentation:

    actionId int: Identifier of the action. This will be either the identifier you supplied, or EditorInfo#IME_NULL if being called due to the enter key being pressed.

    So the proper way to handle enter key events would be:

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        if (actionId == EditorInfo.IME_NULL) {
            // Handle return key here
            return true;
        }
        return false;
    }
    
    0 讨论(0)
  • 2020-12-03 11:07

    I found that my "bug-like behavior" was due to imeActionLabel complicating things. I only used it because it was mentioned in the Text Fields Guide as a way to have a custom return key label. Here are the results of my tests in Lollipop,

    Case 1: default, return key symbol = closing angle bracket

    <EditText
        android:singleLine="true"
        android:inputType="textUri"/>
    

    onEditorAction is called once.

    • KeyEvent = null, actionId = 5 = EditorInfo.IME_ACTION_NEXT
      • if return true, cursor remains in EditText, keyboard open
      • if return false, cursor moves to next focusable, keyboard open if necessary

    Case 2: imeOptions, return key symbol = checkmark

    <EditText
        android:singleLine="true"
        android:inputType="textUri"
        android:imeOptions="actionDone"/>
    

    onEditorAction is called once.

    • KeyEvent = null, actionId = 6 = EditorInfo.IME_ACTION_DONE
      • if return true, cursor remains in EditText, keyboard open
      • if return false, cursor remains in EditText, keyboard closes

    Case 3: imeActionLabel, return key symbol = "URdone"

    <EditText
        android:singleLine="true"
        android:inputType="textUri"
        android:imeOptions="actionDone"
        android:imeActionLabel="URdone"/>
    

    onEditorAction can be called more than once.

    • KeyEvent = null, actionId = 0

      • if return true, cursor remains in EditText, keyboard open, onEditorAction is NOT called a second time
      • if return false, onEditorAction is called a SECOND time:
    • KeyEvent = KeyEvent.ACTION_DOWN, actionId = 0

      • if return false, cursor moves to next focusable, keyboard open if necessary, onEditorAction is NOT called a third time
      • if return true, onEditorAction is called a THIRD time:
    • KeyEvent = KeyEvent.ACTION_UP, actionId = 0

      • if return true, cursor remains in EditText, keyboard open
      • if return false, cursor moves to next focusable, keyboard open if necessary

    NOTES:

    I'm not sure if actionId = 0 is from EditorInfo.IME_ACTION_UNSPECIFIED or EditorInfo.IME_NULL.

    If the next focusable is non-editable, the return key symbol becomes a left pointing arrow.

    You can also use setOnFocusChangeListener to override onFocusChange, which will be called according to the above cursor behavior.

    0 讨论(0)
  • 2020-12-03 11:08

    Beside KeyEvent.ACTION_UP we also need to capture KeyEvent.ACTION_DOWN. Unless KeyEvent.ACTION_UP will never be passed to EditText so our onEditorAction will not work. Example:

    @Override
    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
        final boolean isEnterEvent = event != null
                && event.getKeyCode() == KeyEvent.KEYCODE_ENTER;
        final boolean isEnterUpEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_UP;
        final boolean isEnterDownEvent = isEnterEvent && event.getAction() == KeyEvent.ACTION_DOWN;
    
        if (actionId == EditorInfo.IME_ACTION_DONE || isEnterUpEvent ) {
            // Do your action here
            performLogin();
            return true;
        } else if (isEnterDownEvent) {
            // Capture this event to receive ACTION_UP
            return true;
        } else {
            // We do not care on other actions
            return false;
        }
    }
    

    You have to replace EditorInfo.IME_ACTION_DONE to correct version of EditorInfo.IME_ACTION_ according to android:imeOptions="actionNext"

    0 讨论(0)
  • 2020-12-03 11:08

    It might be worth noting, that you can get more than one event for the click on Enter (depending on the android version). One for the KeyDown (KeyEvent.ACTION_DOWN), one for the KeyUp (KeyEvent.ACTION_UP). When I forgot to check that I accidentally started two server calls for the same action.

    searchBox.setOnEditorActionListener(new OnEditorActionListener() {
    // enter key in search box triggers search
    @Override
    public boolean onEditorAction(TextView v, int actionId,
            KeyEvent event) {
        if ((event != null && event.getAction() == KeyEvent.ACTION_UP) || event==null) {
            onSearchButtonClicked();
        }
        return true;
    }
    });
    
    0 讨论(0)
提交回复
热议问题