Android focus search returned a view that wasn't able to take focus!

Android在 ListView或RecyclerView 的item中EditText 设置imeOptions、imeActionId、imeActionLabel属性导致的异常分析与处理

在设置EditText中设置了这些ime的属性,在点击键盘的回车键时候,会导致
focus search returned a view that wasn't able to take focus!异常的出现

什么原因呢?

查看TextVie源码发现在点击键盘的回车键会通过EditableInputConnection来执行onEditorAction方法

public void onEditorAction(int actionCode) {
        //设置了ime属性mEditor就不为空
        final Editor.InputContentType ict = mEditor == null ? null : mEditor.mInputContentType;
        if (ict != null) {
            if (ict.onEditorActionListener != null) {
                //利用这里的return解决异常
                if (ict.onEditorActionListener.onEditorAction(this,
                        actionCode, null)) {
                    return;
                }
            }
        
            if (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;

            } else if (actionCode == EditorInfo.IME_ACTION_DONE) {
                InputMethodManager imm = InputMethodManager.peekInstance();
                if (imm != null && imm.isActive(this)) {
                    imm.hideSoftInputFromWindow(getWindowToken(), 0);
                }
                return;
            }
        }
        //省略不重要的代码
    }

从代码可以看出actionCode == EditorInfo.IME_ACTION_PREVIOUS
actionCode == EditorInfo.IME_ACTION_PREVIOUS 这里可能会出现异常,异常的原因是查询上一个或下一个view的焦点的时候失败了 抛出了异常

解决办法

这两处抛出异常的代码上方有个return,如果能保证
ict.onEditorActionListener.onEditorAction(this, actionCode, null)永远为true那么异常代码就永远不会执行
即设置EditText的onEditorActionListener()

 editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                //可以根据需求获取下一个焦点还是上一个
                View nextView = v.focusSearch(View.FOCUS_DOWN);
                if (nextView != null) {
                    nextView.requestFocus(View.FOCUS_DOWN);
                }
                //这里一定要返回true
                return true;
            }
        });

你可能感兴趣的:(Android focus search returned a view that wasn't able to take focus!)