Showing the soft keyboard for SearchView on Action

2019-03-25 09:35发布

We've got a SearchView on the ActionBar which is set to be non-iconified. As we don't have any content in the view until the user's entered something to search for, it would make sense to give the SearchView initial focus, and make sure the soft keyboard is showing ready for the user to enter text — otherwise they'll always have to first tap in the SearchView.

I can give the SearchView focus by just calling

searchView.requestFocus();

but I can't get the soft keyboard to appear. In another one of our Fragments I have an EditText which we want to be focused I can get the soft keyboard to appear there by calling

InputMethodManager mgr = (InputMethodManager)getActivity().getSystemService(
            Context.INPUT_METHOD_SERVICE);
mgr.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);

but this just doesn't work on the SearchView. It must surely be possible to get this to work.

7条回答
家丑人穷心不美
2楼-- · 2019-03-25 09:42

I have a similar problem where none of the proposed solutions here worked. Some just didn't make the keyboard appear at all and some show a keyboard but the key presses there just do not work.

The only thing that worked was:

                    // hack for making the keyboard appear
                    searchView.setIconified(true);
                    searchView.setIconified(false);
查看更多
你好瞎i
3楼-- · 2019-03-25 09:44

You can try what I did. This worked well for me.

    //set query change listener
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
        @Override
        public boolean onQueryTextChange(String newText) {
            // TODO Auto-generated method stub
            return false;
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            /**
             * hides and then unhides search tab to make sure keyboard disappears when query is submitted
             * 4 = INVISIBLE
             * 0 = VISIBLE
             */
                  searchView.setVisibility(4);
                  searchView.setVisibility(0);
            return false;
        }

     });  
查看更多
冷血范
4楼-- · 2019-03-25 09:50

Use expandView method : Your onCreateOptionsMenu could be something like this:

         @Override                                                                                                     
       public boolean onCreateOptionsMenu(Menu menu) {                                                          
 //Used to put dark icons on light action bar                                                              

     final SearchView searchView = new SearchView(getSupportActionBar().getThemedContext());                   


       MenuItem mitem = menu.add("Search");                                                                  

       mitem.setIcon(ic_search_inverse)                                                                      
            .setActionView(searchView)                                                                       
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);

        mitem.expandActionView();                                                      

        listsearch.setOnItemClickListener(this);                                                             

 return     true;                                                                                              
      }  
查看更多
放荡不羁爱自由
5楼-- · 2019-03-25 09:54

It worked for me.

private SearchView mSearchView;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);

    SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    MenuItem searchItem = menu.findItem(R.id.action_search);
    mSearchView =
            (SearchView) searchItem.getActionView();
    mSearchView.setSearchableInfo(
            searchManager.getSearchableInfo(getComponentName()));

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_search) {
        mSearchView.setIconifiedByDefault(true);
        mSearchView.setFocusable(true);
        mSearchView.setIconified(false);
        mSearchView.requestFocusFromTouch();
    }

    return super.onOptionsItemSelected(item);
}
查看更多
可以哭但决不认输i
6楼-- · 2019-03-25 09:57

Further rummaging around StackOverflow and I found this question:

Forcing the Soft Keyboard open

which contains a solution that worked for me:

((InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE)).
    toggleSoftInput(InputMethodManager.SHOW_FORCED,
                    InputMethodManager.HIDE_IMPLICIT_ONLY);
查看更多
爷、活的狠高调
7楼-- · 2019-03-25 10:04

I am using a SearchView with setIconifiedByDefault(false). Testing with Android 4.4.2, the only way I could get the keyboard to actually show was to look at the source code for SearchView and mimic how it requested the keyboard to be shown. I've tried literally every other method I could find/think of and this is the only way I could get the keyboard to show reliably. Unfortunately, my method requires some reflection.

In onCreateOptionsMenu(Menu):

searchView.requestFocus();
searchView.post(new Runnable() {
    @Override
    public void run() {
        showSoftInputUnchecked();
    }
});

And then create a method to call the hidden method "showSoftInputUnchecked" in InputMethodManager:

private void showSoftInputUnchecked() {
    InputMethodManager imm = (InputMethodManager)
            getSystemService(Context.INPUT_METHOD_SERVICE);

    if (imm != null) {
        Method showSoftInputUnchecked = null;
        try {
            showSoftInputUnchecked = imm.getClass()
                    .getMethod("showSoftInputUnchecked", int.class, ResultReceiver.class);
        } catch (NoSuchMethodException e) {
            // Log something
        }

        if (showSoftInputUnchecked != null) {
            try {
                showSoftInputUnchecked.invoke(imm, 0, null);
            } catch (IllegalAccessException e) {
                // Log something
            } catch (InvocationTargetException e) {
                // Log something
            }
        }
    }
}

As with all solutions that access methods not in the public API, I can't promise that this won't break with new versions of Android.

查看更多
登录 后发表回答