web-dev-qa-db-fra.com

OnCloseListener de SearchView ne fonctionne pas

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
91
Michell Bak

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;
}
135
niki huang

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

Réf: onActionCollapse/onActionExpand

59
lomza

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);

}
27
Ben Benson

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

17
Dario

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; }
        });
7
Michell Bak

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;
        }
    });
6
Sushant

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>
2
Julio Betta

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.

2
gkl

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.

1
Ray Hunter

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;
                    }
}
0
Nativ

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.

0
Sean

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).

0
Joseph Earl
    searchView.setOnCloseListener {
        d("click", "close clicked")
        return@setOnCloseListener false
    }

si vous cliquez sur fermer searchView ->

D/clic: fermer cliqué

0
Oleksandr Yahnenko

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
            }
        }
0
Psylocke