web-dev-qa-db-fra.com

Action de repli automatique ActionBar SearchView on Soft Keyboard close

J'utilise actuellement un élément de menu ActionBar pour afficher un SearchView dans la barre d'actions. Lorsque l'élément de menu de recherche est développé, le clavier virtuel s'affiche, ce que je veux. Maintenant, lorsque l'utilisateur appuie sur le bouton de retour pour fermer le clavier virtuel, je voudrais également réduire le SearchView dans la barre d'action.

J'ai essayé d'implémenter les écouteurs suivants OnKeyListener et OnFocusChangeListener sur le MenuItem et l'ActionView. J'ai également essayé d'utiliser OnBackPressed () dans l'activité. Aucun des éléments ci-dessus ne détecte lorsque le bouton de retour est utilisé pour fermer le clavier virtuel.

Des idées?

J'ai implémenté OnActionExpandListener pour savoir quand le SearchView est visible.

76
user1258568

Je vais développer la réponse de @ user1258568 pour les paresseux. Cela a fonctionné pour moi. Notez qu'il efface votre requête lorsque le focus est perdu.

final MenuItem searchMenuItem = optionsMenu.findItem(R.id.search);
final SearchView searchView = (SearchView) searchMenuItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean queryTextFocused) {
        if(!queryTextFocused) {
            searchMenuItem.collapseActionView();
            searchView.setQuery("", false);
        }
    }
});
99
Jon Willis

J'ai trouvé une meilleure solution.

searchView.setOnQueryTextFocusChangeListener(). 

OnQueryTextFocusChangeListener est appelé lorsque le clavier est affiché ou masqué. Obtient appelé en premier lorsque le clavier est affiché et la vue de recherche aura le focus. Obtient à nouveau lorsque keyboard est masqué et que la vue de recherche perd le focus, peut close search viewen utilisant ensuite

menuItem.collapseActionView().
37
user1258568

Remplacez simplement onBackPressed comme ceci:

@Override
    public void onBackPressed() {
        if (searchView.isShown()){
            searchView.onActionViewCollapsed();  //collapse your ActionView
            searchView.setQuery("",false);       //clears your query without submit
            isClosed = true;                     //needed to handle closed by back
        } else{
            super.onBackPressed();
        }
    }

et votre onCreateOptionsMenu gonflerait le mSearchView comme ceci:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.menu_search, menu);
        mSearchView = (SearchView) menu.findItem(R.id.menu_action_search).getActionView();
        mSearchView.setOnQueryTextListener(this);
        mSearchView.setOnSearchClickListener(this);
        mSearchView.setOnCloseListener(this);
        isClosed = true;
        return true;
    }

avez-vous la classe implémenter ce qui suit comme ceci:

public class myActivity extends FragmentActivity implements
    SearchView.OnQueryTextListener, View.OnClickListener, SearchView.OnCloseListener {

dont vous aurez également besoin:

@Override
public void onClick(View view) {
    isClosed = false;
}

@Override
public boolean onClose() {
    isClosed = true;
    return false;
}

Vous devrez créer "mSearchView" et "isClosed" les deux variables globales de l'activité.

10
Codeversed

Il vous suffit de mettre l'attribut "collapseActionView" dans la disposition du menu

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
      xmlns:app="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/menu_item_search"
        Android:title="@string/search"
        Android:iconifiedByDefault="true"
        Android:icon="@drawable/ic_action_search" 
        app:actionViewClass="Android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView"/> <--this one
</menu>

Cela vous donnera la fonctionnalité que vous recherchez toute seule. N'oubliez pas d'appeler la méthode "clearFocus" sur le SearchView pour fermer le clavier une fois que vous avez envoyé la requête.

2
Rodrigo de Blas

La réponse de Jon Willis fonctionne très bien. Il s'agit d'une amélioration de sa réponse.

Créez d'abord une nouvelle classe qui implémente View.OnFocusChangeListener:

public class SearchViewFocusListener implements View.OnFocusChangeListener {

    private final MenuItem mMenuItem;

    public SearchViewFocusListener(MenuItem menuItem) {
        mMenuItem = menuItem;
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            mMenuItem.collapseActionView();
            if (v instanceof SearchView) {
                ((SearchView) v).setQuery("", false);
            }
        }
    }

}

Ensuite, définissez l'écouteur sur votre SearchView:

searchView.setOnQueryTextFocusChangeListener(new SearchViewFocusListener(menuItem));
2
Jared Rummler

C'est réalisable comme ceci:

   private void setupSearchView(Menu menu) {
        final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
        final SearchView searchView = (SearchView) searchMenuItem.getActionView();

        [...]

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                searchMenuItem.collapseActionView();
                return false;
            }
            @Override
            public boolean onQueryTextChange(String newText) {
                return true;
            }
        });
    }

Les solutions basées sur setOnQueryTextFocusChangeListener () n'ont pas fonctionné pour moi car l'événement n'a pas été lancé - le searchView n'a pas perdu le focus lorsqu'il est soumis, probablement parce que j'effectue la recherche dans la même activité qui contient la vue de recherche.

Quoi qu'il en soit, je pense que l'utilisation d'OnQueryTextListener est plus correcte, car elle décrit plus précisément l'événement de soumission de texte.

1
GaRRaPeTa

C'est ce que j'ai fait pour faire disparaître le clavier. Vous pouvez essayer de voir si cela fonctionne pour vous. J'ai mis le searchView sur invisible puis sur visible à nouveau.

    //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
             */
                  searchView.setVisibility(View.INVISIBLE);
                  searchView.setVisibility(View.VISIBLE);
            return false;
        }

     });
1
Parnit

Si vous souhaitez réduire le clavier lorsque l'utilisateur clique sur l'icône de recherche sur le clavier, cela peut être réalisé par simple

inside onquerytextsubmitted {

searchView.clearfocus()

}

0
geniushkg
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.home_screen, menu);

        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        final MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
        final SearchView searchView = (SearchView) searchMenuItem
                .getActionView();
        searchView.setIconifiedByDefault(false);
        if (searchManager != null && searchView != null) {
            searchView.setSearchableInfo(searchManager
                    .getSearchableInfo(getComponentName()));

            searchView
                    .setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {

                        @Override
                        public void onFocusChange(View v, boolean hasFocus) {

                            if (!hasFocus) {
                                if (searchMenuItem != null) {
                                    searchMenuItem.collapseActionView();
                                }// end if
                                if (searchView != null) {
                                    searchView.setQuery("", false);

                                }// end if
                            }// end if

                        }
                    });

            searchView
                    .setOnQueryTextListener(new SearchView.OnQueryTextListener() {

                        @Override
                        public boolean onQueryTextSubmit(String query) {
                            /**
                             * hides and then unhides search tab to make sure
                             * keyboard disappears when query is submitted
                             */
                            if (searchView != null) {
                                searchView.setVisibility(View.INVISIBLE);
                                searchView.setVisibility(View.VISIBLE);

                            }
                            return false;
                        }

                        @Override
                        public boolean onQueryTextChange(String newText) {
                            // TODO Auto-generated method stub
                            return false;
                        }
                    });

        }

        return super.onCreateOptionsMenu(menu);
    }
0
confucius

Pour une raison quelconque, menuItem.collapseActionView() ne fonctionnait pas, j'ai donc utilisé searchView.setIconified(true) à la place.

Cela donne le résultat ci-dessous comme exemple de code.

final MenuItem searchItem = (MenuItem) menu.findItem(R.id.menu_item_search);
final SearchView searchView = (SearchView) searchItem.getActionView();

searchView.setOnQueryTextFocusChangeListener(new SearchView.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            searchView.setIconified(true);
        }
    }
});
0
bastien

Vous devez appeler setIconified deux fois.

Pour réduire réellement votre vue de recherche et fermer le clavier.
Avec le premier appel, le texte de la vue de recherche est effacé avec le clavier du deuxième appel et la vue de recherche se ferme.

0
nosaiba darwish