web-dev-qa-db-fra.com

Commencer une nouvelle activité à partir de SearchView

J'ai 2 activités: la première a une barre d'action avec une vue de recherche, la seconde doit afficher les résultats de la requête de recherche.

androidmanifest:

    <activity
        Android:name=".SearchActivity"

        ...
        Android:launchMode="singleTop">           

        <meta-data
            Android:name="Android.app.searchable"
            Android:resource="@xml/searchable" />
        ...

    </activity>

   <activity
        Android:name=".ResultsActivity"
        ...

         <intent-filter>
            <action Android:name="Android.intent.action.SEARCH" />
        </intent-filter>

    </activity>

consultable.xml

<searchable
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:label="@string/app_name"
Android:hint="@string/enter_a_Word" />

RechercherActivité

....
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_noun_list, menu);

    // Associate searchable configuration with the SearchView
    SearchManager searchManager =  (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView =  (SearchView) menu.findItem(R.id.search).getActionView();
    searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName()));

    return true;
}
....

RésultatsActivité:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);

    }
...
}

le problème est qu'après la saisie d'une requête dans la vue de recherche, rien ne se produit. Aucune erreur, rien. Comment puis-je ouvrir les résultats après la saisie de la requête dans la recherche?

15
Maarten

Cette réponse est un peu en retard mais je pense que cela sera utile pour les futurs téléspectateurs. Le dilemme semble provenir de l'ambiguïté du tutoriel Android SearchView. Le scénario couvert suppose que les résultats seront affichés dans la même activité que le SearchView. Dans un tel scénario, la balise Activity du fichier AndroidManifest.xml ressemblerait à ceci:

<activity
    Android:name=".MainActivity"
    Android:label="@string/main_activity_label"
    Android:launchMode="singleTop">
        <intent-filter>
            <action Android:name="Android.intent.action.SEARCH"/>
        </intent-filter>
        <meta-data Android:name="Android.app.searchable"
            Android:resource="@xml/searchable" />
</activity>

Ensuite, pour gérer les résultats dans la même activité, vous devez remplacer la méthode onNewIntent:

@Override
public void onNewIntent(Intent intent){
    setIntent(intent);
    if(Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        //now you can display the results
    }  
}

Cependant, dans une situation où nous souhaitons afficher les résultats dans une autre activité, nous devons insérer le filtre d'intention et la balise méta dans l'activité de résultats et introduire une nouvelle balise méta pour l'activité SearchView. Ainsi, nos activités ressembleront à ceci dans le fichier AndroidManifest.xml:

<activity
        Android:name=".MainActivity"
        Android:label="@string/main_activity_label"
        Android:launchMode="singleTop">
        <!-- meta tag points to the activity which displays the results -->
        <meta-data
            Android:name="Android.app.default_searchable"
            Android:value=".SearchResultsActivity" />
</activity>
<activity
        Android:name=".SearchResultsActivity"
        Android:label="@string/results_activity_label"
        Android:parentActivityName="com.example.MainActivity">
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            Android:name="Android.support.PARENT_ACTIVITY"
            Android:value="com.example.MainActivity" />
        <!-- meta tag and intent filter go into results activity -->
        <meta-data Android:name="Android.app.searchable"
            Android:resource="@xml/searchable" />
        <intent-filter>
            <action Android:name="Android.intent.action.SEARCH" />
        </intent-filter>
</activity>

Ensuite, dans la méthode onCreateOptionsMenu de notre MainActivity, activez SearchView (en supposant que vous ajoutiez SearchView au ActionBar). Plutôt que d'utiliser getComponentName() dans l'appel à la méthode getSearchableInfo () du SearchManager, nous instancierons un nouvel objet ComponentName en utilisant le contexte de MainActivity et la classe SearchResultsActivity:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_home, menu);
    SearchView search = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search);
    // Associate searchable configuration with the SearchView
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    search.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchResultsActivity.class)));
    search.setQueryHint(getResources().getString(R.string.search_hint));
    return true;
}

Enfin, dans notre classe SearchResultsActivity, dans la méthode onCreate, nous pouvons gérer les résultats de la recherche:

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        //use the query to search your data somehow
    }
}

N'oubliez pas pour créer le fichier de ressources searchable.xml et ajouter SearchView à votre mise en page.

searchable.xml (res/xml/searchable.xml; créer un dossier xml sous res si nécessaire):

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:label="@string/app_name"
    Android:hint="@string/search_hint"
    Android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>

Layout (exemple d’ajout de SearchView à ActionBar en tant qu’élément de menu):

<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="com.example.MainActivity">
    <group Android:checkableBehavior="single">
        <item Android:id="@+id/action_search" Android:title="Search"
            Android:orderInCategory="1" app:showAsAction="collapseActionView|ifRoom"
            app:actionViewClass="Android.support.v7.widget.SearchView"/>
    </group>
</menu>

Ressources:

28
chRyNaN

J'ai compris le problème que j'avais également rencontré le même, cela se produit parce que vous passez le nom du composant actuel en passant le

getComponentName ()

Cela sera initialisé par le nom de l'activité en cours. Vous devez donc l'initialiser avec le nom de l'activité de recherche dans le format donné ci-dessous et transmettre la même instance de composant que celle qui a démarré la nouvelle activité.

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    search.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchResultsActivity.class)));
    search.setQueryHint(getResources().getString(R.string.search_hint));

J'espère que j'ai répondu à la question!

0
Vivek Kumar Samele

Sans voir votre code d'activité, je vous suggérerais d'essayer cette approche - en supposant que tous les fichiers soient créés comme indiqué ci-dessus;

Dans votre activité de résultats,

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.core_actions, menu);

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

    searchView.setIconifiedByDefault(false);
    searchView.setQueryHint(getString(R.string.search_hint));

    searchView.setOnQueryTextListener(this);

    return true;
}

N'oubliez pas qu'il s'agit de l'activité pour laquelle vous souhaitez rendre les données accessibles à vos données:

Vous devez implémenter l'interface SearchView.OnQueryTextListener dans la même activité:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_search:
            ProductsResulstActivity.this.finish();

            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {

    productFilterAdapter.getFilter().filter(newText);

    if (TextUtils.isEmpty(newText)) {
         listView.clearTextFilter();
     }
    else {
       listView.setFilterText(newText);
    }

    return true;
}

productFilterAdapter est l'adaptateur que vous devez créer au préalable.

Il devrait implémenter une interface filtrable. J'espère que ça aide.

Si vous avez besoin d'aide supplémentaire, s'il vous plaît faites le moi savoir. Bonne chance

0
Eenvincible