J'essaie d'ajouter une prise en charge de SearchView
dans la barre d'outils Android 3.0+, mais je ne parviens pas à faire fonctionner OnCloseListener
.
Voici mon code:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
searchView = (SearchView) menu.findItem(R.id.search_textbox).getActionView();
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
searchLibrary(newText);
return false;
}
@Override
public boolean onQueryTextSubmit(String query) { return false; }
});
searchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
System.out.println("Testing. 1, 2, 3...");
return false;
}
});
return true;
}
La recherche fonctionne très bien et tout fonctionne sauf la OnCloseListener
. Rien n'est imprimé sur Logcat. Voici le Logcat pour quand j'appuie sur le bouton "Fermer":
02-17 13:01:52.914: I/TextType(446): TextType = 0x0
02-17 13:01:57.344: I/TextType(446): TextType = 0x0
02-17 13:02:02.944: I/TextType(446): TextType = 0x0
J'ai parcouru la documentation et des exemples, mais rien ne semblait les changer. Je l’utilise sur un Asus Transformer Prime et un Galaxy Nexus, tous deux sur un sandwich à la crème glacée. Des idées?
Mettre à jour:
Oui - System.out.println()
fait fonctionne. Voici la preuve:
@Override
public boolean onQueryTextChange(String newText) {
System.out.println(newText + "hello");
searchLibrary(newText);
return false;
}
Résultats dans ce Logcat:
02-17 13:04:20.094: I/System.out(21152): hello
02-17 13:04:24.914: I/System.out(21152): thello
02-17 13:04:25.394: I/System.out(21152): tehello
02-17 13:04:25.784: I/System.out(21152): teshello
02-17 13:04:26.064: I/System.out(21152): testhello
Je rencontre aussi ce problème et je n’ai pas d’autre choix que d’abandonner "oncloselistener". Au lieu de cela, vous pouvez obtenir votre menuItem, puis setOnActionExpandListener
. Ensuite, remplacez les méthodes non-imaginaires.
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// TODO Auto-generated method stub
Log.d("*******","onMenuItemActionExpand");
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
//do what you want to when close the sesarchview
//remember to return true;
Log.d("*******","onMenuItemActionCollapse");
return true;
}
Pour Android API 14+ (ICS et supérieur), utilisez ce code:
// When using the support library, the setOnActionExpandListener() method is
// static and accepts the MenuItem object as an argument
MenuItemCompat.setOnActionExpandListener(menuItem, new OnActionExpandListener() {
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
// Do something when collapsed
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
// Do something when expanded
return true; // Return true to expand action view
}
});
Pour plus d'informations: http://developer.Android.com/guide/topics/ui/actionbar.html#ActionView
Pour ce problème, je suis arrivé avec quelque chose comme ça,
private SearchView mSearchView;
@TargetApi(14)
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.conversation_index_activity_menu, menu);
mSearchView = (SearchView) menu.findItem(R.id.itemSearch).getActionView();
MenuItem menuItem = menu.findItem(R.id.itemSearch);
int currentapiVersion = Android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= Android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
menuItem.setOnActionExpandListener(new OnActionExpandListener()
{
@Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
// Do something when collapsed
Log.i(TAG, "onMenuItemActionCollapse " + item.getItemId());
return true; // Return true to collapse action view
}
@Override
public boolean onMenuItemActionExpand(MenuItem item)
{
// TODO Auto-generated method stub
Log.i(TAG, "onMenuItemActionExpand " + item.getItemId());
return true;
}
});
} else
{
// do something for phones running an SDK before froyo
mSearchView.setOnCloseListener(new OnCloseListener()
{
@Override
public boolean onClose()
{
Log.i(TAG, "mSearchView on close ");
// TODO Auto-generated method stub
return false;
}
});
}
return super.onCreateOptionsMenu(menu);
}
J'ai rencontré le même problème sur Android 4.1.1. On dirait qu'il s'agit d'un bogue connu: https://code.google.com/p/Android/issues/detail?id=25758
Quoi qu'il en soit, en guise de solution de contournement, j’ai utilisé un écouteur à changement d’état (lorsque SearchView est détaché de la barre d’action, il est également évidemment fermé).
view.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewDetachedFromWindow(View arg0) {
// search was detached/closed
}
@Override
public void onViewAttachedToWindow(View arg0) {
// search was opened
}
});
Le code ci-dessus a bien fonctionné dans mon cas.
Je poste la même réponse ici: https://stackoverflow.com/a/24573266/2162924
J'ai fini par utiliser un peu de bidouille, cela fonctionne bien pour mon but - je ne suis pas sûr que cela fonctionne à toutes fins. Quoi qu'il en soit, je vérifie si la requête de recherche est vide. Ce n'est pas vraiment lié à la SearchView
's OnCloseListener
cependant - cela ne fonctionne toujours pas!
searchView.setOnQueryTextListener(new OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
if (newText.length() > 0) {
// Search
} else {
// Do something when there's no input
}
return false;
}
@Override
public boolean onQueryTextSubmit(String query) { return false; }
});
Eh bien, cela a résolu mon problème:
Article de menu avec showAsAction="always"
<item
Android:id="@+id/action_search"
Android:icon="@drawable/ic_action_search"
Android:title="Search"
app:actionViewClass="Android.support.v7.widget.SearchView"
app:showAsAction="always"/>
et en activité
searchView.setOnCloseListener(new OnCloseListener() {
@Override
public boolean onClose() {
Log.i("SearchView:", "onClose");
searchView.onActionViewCollapsed();
return false;
}
});
Pour que OnCloseListener
fonctionne, assurez-vous que showAsAction
est défini sur always
dans l'élément de menu de recherche.
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
tools:context=".SearchActivity">
<item
Android:id="@+id/search"
Android:title="@string/search"
Android:icon="@drawable/ic_search_toolbar"
app:showAsAction="always"
app:actionViewClass="Android.support.v7.widget.SearchView"/>
</menu>
J'ai rencontré le même problème avec onCloseListener qui n'appelle pas pour SearchView . Comprenez le problème de bogue soulevé dans 25758 , et quelques publications que j'ai lues, pour appeler onCloseListener, vous devez définir:
searchView.setIconifiedByDefault(true);
Mais pour mon cas, je voulais que la vue de recherche soit ouverte et non iconifiée tout le temps. Je parviens à résoudre ce problème en ajoutant une ligne supplémentaire ci-dessous:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_bar, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(queryTextListener);
searchView.setIconifiedByDefault(true);
searchView.setIconified(false);
return true;
}
SearchView.setIconified (false) entraînera l'ouverture de searchView, bien que la valeur par défaut soit iconifiée sur true dans la ligne précédente. De cette façon, j'ai réussi à avoir à la fois un SearchView Qui s'ouvre tout le temps et qu'il appelle l'invocation onCloseListener.
Pour le problème MenuItemCompat
, j'ai ajouté ViewTreeObserver pour suivre l'état de visibilité. Vous pouvez consulter ma réponse ici: https://stackoverflow.com/a/28762632/1633609
Créez l'élément de menu avec le app:showAsAction
défini sur always.
<item
Android:id="@+id/action_search"
Android:title="..."
Android:icon="..."
app:actionViewClass="Android.support.v7.widget.SearchView"
app:showAsAction="always"/>
Lors de la création de la variable SearchView
dans la méthode onCreateOptionsMenu
, effectuez une opération similaire.
inflater.inflate(R.menu.menu_search, menu);
final MenuItem item = menu.findItem(R.id.action_search);
final SearchView search = (SearchView) item.getActionView();
search.setQueryHint(getString(R.string.search_brand_item));
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
// add your code
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// add your code
return false;
}
});
search.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
// add your code here
return false;
}
});
search.setIconifiedByDefault(true); // make sure to set this to true
La search.setIconifiedByDefault(true)
doit être définie sur true
pour appeler la méthode onClose()
sur la SearchView.OnCloseListener()
créée ci-dessus.
C'est une solution de contournement mais qui a fonctionné pour moi
searchView.setOnQueryTextListener(new Android.widget.SearchView.OnQueryTextListener() {
String lastText;
@Override
public boolean onQueryTextChange(final String newText) {
if (lastText != null && lastText.length() > 1 && newText.isEmpty()) {
// close ctn clicked
return true;
}
}
semble un vieux fil déjà, mais je pensais avoir le même problème API 18 au début. Après avoir googlé, trouvé ce fil, une heure plus tard, j'ai lu le javadoc essayé et errant pour quelque chose que je ne prétends pas bien comprendre en javadoc.
searchView.setIconifiedByDefault(true);
// OnQueryTextListener
@Override
public boolean onQueryTextSubmit(String query) {
Log.d(tag, "onQueryTextSubmit: " + query);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
Log.d(tag, "onQueryTextChange: " + query);
return true;
}
// OnCloseListener
@Override
public boolean onClose() {
Log.w(tag, "onClose: ");
return false;
}
J'ai un peu joué avec vrai/faux, ça fait la différence, et ça marche pour moi maintenant. Espérons que cela pourrait sauver du temps à quelqu'un.
La raison pour laquelle OnCloseListener
n'est pas appelée, c'est parce qu'il y a un bogue dans le code Android - l'auditeur n'est appelé que si vous appelez également setIconifiedByDefault(true)
.
searchView.setOnCloseListener {
d("click", "close clicked")
return@setOnCloseListener false
}
si vous cliquez sur fermer searchView ->
D/clic: fermer cliqué
J'ai rencontré ce problème en essayant de détecter l'affichage/le retrait de SearchView. J'ai fini par utiliser un auditeur différent et cela a fonctionné pour ce dont j'avais besoin:
setOnQueryTextFocusChangeListener { _, hasFocus ->
if (hasFocus) {
// SearchView is being shown
} else {
// SearchView was dismissed
}
}