即使明确要求,Android键盘也不会出现 [英] Android keyboard not appearing, even when explicitly requested

查看:148
本文介绍了即使明确要求,Android键盘也不会出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含两个活动的应用程序,有时,我需要切换活动,同时在刚刚恢复的活动的操作栏中打开搜索输入.一切正常,除了我无法拿起键盘.我的代码的相关位如下(注意:如果需要搜索输入,则由于切换活动而将布尔值startsearch设置为true):

I have an app with two activities, and sometimes, I need to switch activity and at the same time open up the search input in the actionbar of the activity that's just been resumed. Everything works fine, except that I can't get the keyboard to come up. The relevant bits of my code are below (NB: the boolean startsearch is set true as a result of switching activities if the search input is required):

public class MyActivity extends Activity {

    private InputMethodManager imm;
    public  boolean startsearch;
    private MenuItem DestinationTxt;
    private SearchView mySearchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // various initialisation, and then:
        startsearch = false;
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_menu, menu);     
        DestinationTxt = menu.findItem(R.id.actionbar_search);
        mySearchView = (SearchView)DestinationTxt.getActionView();
        // more menu create stuff appears here      
    }

    @Override
    public void onResume() {
        super.onResume();
        if (startsearch) {
            DestinationTxt.expandActionView();
            imm.showSoftInput(mySearchView, 0);
        }
    }
}

,而action_menu.xml的相关位是

and the relevant bit of the action_menu.xml is

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@+id/actionbar_search"
        android:orderInCategory="1"
        android:showAsAction="always|withText|collapseActionView"
        android:actionViewClass="android.widget.SearchView"
        android:icon="@drawable/earth_2508858_search_en"
        android:inputType="textPostalAddress"
        android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"></item>
</menu>

就像我说的那样,这在大多数情况下都是可行的,因为在活动恢复时,操作栏搜索确实会获得焦点.但是键盘没有出现,尽管(我从代码中可以看到),我已经明确要求了它.谁能告诉我我在做什么错,以及我需要做些什么才能使键盘弹起来?

As I said, this mostly works, because the action bar search does get the focus when the activity resumes. But the keyboard doesn't appear, even though (as you can see from the code), I've explicitly requested it. Can anyone tell me what I'm doing wrong, and what I need to do to get the keyboard to come up?

推荐答案

我现在已经能够弄清楚这一点.通过查看InputMethodManager.showSoftInput(View, int)的代码,我发现我提出键盘的请求被忽略了,因为我传递的视图不是InputMethodManager的活动视图.

I've now been able to figure this out. By looking at the code for InputMethodManager.showSoftInput(View, int), I worked out that my request to bring up the keyboard was being ignored because the view I was passing wasn't the InputMethodManager's active view.

为解决我的问题,我在MyActivity类中添加了两个新字段,即:

To solve my problem, I added two new fields to the MyActivity class, namely:

private EditText search_edit_text;
private boolean mySearchView_editflag;

search_edit_text变量将是SearchView mySearchView内部的视图,该视图实际上是获得焦点并从键盘接收输入的视图. mySearchView_editflag通常为false,但在应用程序等待正确的时间打开键盘时为true.

The search_edit_text variable will be the view inside the SearchView mySearchView which is the view that actually gets the focus and receives the input from the keyboard. The mySearchView_editflag will normally be false, but it will be true when the app is waiting for the right time to bring up the keyboard.

为了掌握search_edit_text EditText对象,我使用了以下函数

To get hold of the search_edit_text EditText object I used the following function

public static EditText GetEditText(ViewGroup vg) {
    for(int i=0; i< vg.getChildCount(); i++) {
        View v = vg.getChildAt(i);
        if (v instanceof EditText) {
            return (EditText)v;
        } else if (v instanceof ViewGroup) {
            EditText et = GetEditText((ViewGroup)v);
            if (et != null) return et;
        }
    }       
    return null;
}

并更改了我的onCreateOptionsMenu(Menu)函数以包括以下内容

and altered my onCreateOptionsMenu(Menu) function to include the following

DestinationTxt = menu.findItem(R.id.actionbar_search);
mySearchView = (SearchView)DestinationTxt.getActionView();
search_edit_text = GetEditText(mySearchView);
mySearchView_editflag = false;

这将初始化search_edit_textmySearchView_editflag变量.我的onResume()方法更改为

This initializes the search_edit_text and mySearchView_editflag variables. My onResume() method was altered to

@Override
public void onResume() {
    super.onResume();
    if (startsearch) {
        DestinationTxt.expandActionView();
        mySearchView_editflag = true;
    }
}

并且我包含了一些代码,这些代码会频繁调用以下方法:

and I included code which calls the following method at high frequency:

public void CheckStatus() {
    if (mySearchView_editflag && imm.isActive(search_edit_text)) {
        imm.showSoftInput(search_edit_text, 0);
        mySearchView_editflag=false;
    }
}

该应用程序现在可以按我的要求运行,因为在需要在操作栏中进行搜索输入时,跟随活动切换,该应用程序现在一直等到imm.isActive(search_edit_text)为true(这意味着EditText对象正在接收输入)之前,调用imm.showSoftInput(search_edit_text, 0)以确保键盘可见.

This app now works as I want it to, because following the activity switch when search input in the actionbar is required, the app now waits until imm.isActive(search_edit_text) is true (which means the EditText object is receiving input) before calling imm.showSoftInput(search_edit_text, 0) to make sure that the keyboard is visible.

为了帮助我解决所有这些问题,我使用了InputMethodManager.showSoftInput(View, int, ResultReceiver)而不是InputMethodManager.showSoftInput(View, int),所以代替了

To help me work all this out, I used InputMethodManager.showSoftInput(View, int, ResultReceiver) instead of InputMethodManager.showSoftInput(View, int), so instead of

imm.showSoftInput(search_edit_text, 0);

我有

ImmResultsReceiver irr = new ImmResultsReceiver();
imm.showSoftInput(search_edit_text, 0, irr);

其中ImmResultsReceiver是类

public class ImmResultsReceiver extends ResultReceiver {        
    public ImmResultsReceiver() { super(null); }        
    @Override
    protected void onReceiveResult (int resultCode, Bundle resultData) {
        String descrip;
        switch(resultCode) {
            case InputMethodManager.RESULT_UNCHANGED_SHOWN: descrip = "RESULT_UNCHANGED_SHOWN"; break;
            case InputMethodManager.RESULT_UNCHANGED_HIDDEN: descrip = "RESULT_UNCHANGED_HIDDEN"; break;
            case InputMethodManager.RESULT_SHOWN: descrip = "RESULT_SHOWN"; break;
            case InputMethodManager.RESULT_HIDDEN: descrip = "RESULT_HIDDEN"; break;
            default:descrip="InputMethodManager("+resultCode+")"; break;
        }
        Log.d("MyLog", "ImmResultsReceiver,"+descrip+","+(resultData == null?"":"resultData.size()="+resultData.size()));
    }               
}

如果从未调用ImmResultsReceiver.onReceiveResult(...)方法,则意味着对InputMethodManager.showSoftInput(...)的调用已被忽略,因为传递给InputMethodManager.showSoftInput(...)的视图不是InputMethodManager的活动视图.

If the ImmResultsReceiver.onReceiveResult(...) method is never called, it means that the call to InputMethodManager.showSoftInput(...) has been ignored because the view that's passed to InputMethodManager.showSoftInput(...) isn't the InputMethodManager's active view.

这篇关于即使明确要求,Android键盘也不会出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆