web-dev-qa-db-fra.com

Comment ajouter un SearchWidget à la barre d'actions?

J'essaie d'ajouter un SearchViewView à mon application (comme expliqué ici http://developer.Android.com/guide/topics/search/search-dialog.html#UsingSearchWidget ). Malheureusement, je continue à avoir une exception NullPointerException et j'ai du mal à détecter ce qui ne va pas.

J'ai créé une configuration interrogeable et une activité interrogeable, comme indiqué sur la page Android. Mon fichier .xml de menu ressemble à ceci:

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    ...
    <item
        Android:id="@+id/menu_item_search"
        Android:actionViewClass="Android.widget.SearchView"
        Android:icon="@drawable/icon_search"
        Android:showAsAction="always"
        Android:title="@string/action_bar_button_search">
    </item>

</menu>

C'est la méthode où l'exception est levée:

public boolean onCreateOptionsMenu( Menu menu )
{
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate( R.menu.action_bar, menu );

    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();

    // NullPointerException thrown here; searchView is null.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false);

    return super.onCreateOptionsMenu( menu );
}

Trace complète de la pile:

FATAL EXCEPTION: main
Java.lang.NullPointerException
at com.example.activities.Test.onCreateOptionsMenu(Test.Java:41)
at Android.app.Activity.onCreatePanelMenu(Activity.Java:2444)
at com.Android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.Java:408)
at com.Android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.Java:759)
at com.Android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.Java:2997)
at Android.os.Handler.handleCallback(Handler.Java:605)
at Android.os.Handler.dispatchMessage(Handler.Java:92)
at Android.os.Looper.loop(Looper.Java:137)
at Android.app.ActivityThread.main(ActivityThread.Java:4507)
at Java.lang.reflect.Method.invokeNative(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:511)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:790)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:557)
at dalvik.system.NativeStart.main(Native Method)
26
Taig

utiliser cette manière comme dans link

public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar, menu);
        MenuItem searchItem = menu.findItem(R.id.menu_item_search);
        SearchView searchView = (SearchView) searchItem.getActionView();


        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        if(null!=searchManager ) {   
         searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        }
        searchView.setIconifiedByDefault(false);

        return true;
    }
20
Dheeresh Singh

Comme cette question est fréquemment consultée et que je suis tombé sur le même problème encore et encore, voici un petit suivi qui garde une trace de toutes les étapes nécessaires à la création d'un SearchWidget.

Cependant, il y a une partie délicate à propos de SearchWidget: Si vous utilisez des chaînes codées en dur dans searchable.xml au lieu de ressources, l'application se plantera avec un message d'erreur confus. Cela m'a pris beaucoup trop d'heures de ma vie ...

  1. Créer une activité pour gérer les résultats de la recherche

    public class Search extends Activity {}
    
  2. Ajoutez un fichier "searchable.xml" à votre répertoire res/xml ( utilisez les ressources pour le conseil et l'étiquette! )

    <searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:hint="@string/search_hint"
        Android:includeInGlobalSearch="false"
        Android:label="@string/search_label"
        Android:searchSettingsDescription="@string/search_global_description" />
    
  3. Créez l'élément de menu approprié "main.xml" dans le répertoire res/menu

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    
        <item
           Android:id="@+id/options_menu_main_search"
           Android:actionViewClass="Android.widget.SearchView"
           Android:icon="@drawable/icon_magnifier"
           Android:showAsAction="always"
           Android:title="Search"/>
    
    </menu>
    
  4. Mettez à jour votre fichier Manifest.xml: Ajoutez l'activité de recherche et spécifiez les activités susceptibles de recevoir des intentions de recherche. L'ajout de <meta-data Android:name="Android.app.default_searchable" Android:value=".app.Search" /> à un nœud activity le rend consultable. L'ajouter au nœud application permet de rechercher toutes les activités.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:Android="http://schemas.Android.com/apk/res/Android">
        <application>
            <meta-data
                Android:name="Android.app.default_searchable"
                Android:value=".app.Search" />
    
            <activity Android:name=".activities.Search" >
                <intent-filter>
                <action Android:name="Android.intent.action.SEARCH" />
            </intent-filter>
    
            <meta-data
                Android:name="Android.app.searchable"
                Android:resource="@xml/searchable" />
        </activity>
    </application>
    

  5. Ajoutez le SearchManager à votre ActionView dans chaque activité devant fournir le moteur de recherche

    public class Activity extends Android.app.Activity
    {
        @Override
        public boolean onCreateOptionsMenu( Menu menu )
        {
            getMenuInflater().inflate( R.menu.main, menu );
    
            // Add SearchWidget.
            SearchManager searchManager = (SearchManager) getSystemService( Context.SEARCH_SERVICE );
            SearchView searchView = (SearchView) menu.findItem( R.id.options_menu_main_search ).getActionView();
    
            searchView.setSearchableInfo( searchManager.getSearchableInfo( getComponentName() ) );
    
            return super.onCreateOptionsMenu( menu );
        }
    }
    
49
Taig

Si vous utilisez le ciblage Android 2.x et que Android.support.v7.widget.SearchView , Vérifiez que votre menu.xml ressemble à ceci (notez le yourapp namespace).

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:yourapp="http://schemas.Android.com/apk/res-auto">
    <item
        Android:id="@+id/search"
        Android:title="@string/search"
        Android:icon="@drawable/ic_search"
        yourapp:showAsAction="always"
        yourapp:actionViewClass="Android.support.v7.widget.SearchView" />
</menu>

Et dans l'activité où vous gonflez le menu, utilisez:

Android.support.v7.widget.SearchView searchView = (Android.support.v7.widget.SearchView) 
MenuItemCompat.getActionView(menu.findItem(R.id.search));
24
peceps

SearchView getActionView retournant la valeur null

Comme dans le lien, ouvrez votre fichier xml de menu et modifiez 

Android:actionViewClass="Android.widget.SearchView"

dans 

app:actionViewClass="Android.widget.SearchView" 

cela a fonctionné pour moi

7
QuinnX

J'ai aussi le même problème. Dans mon cas, changer Android:actionViewClass en app:actionViewClass a résolu le problème .__ (avec xmlns:app="http://schemas.Android.com/apk/res-auto" dans la balise <menu>).

2
stenlytw

Tout d’abord, créez un fichier XML contenant le SearchWidget dans votre dossier de présentation

<?xml version="1.0" encoding="utf-8"?>
<SearchView xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/edit_query"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:inputType="textFilter"
    >

</SearchView>

Puis, dans votre activité, récupérez la barre d'action

Android.support.v7.app.ActionBar actionBar = getSupportActionBar();

Ajoutez ensuite une référence à votre vue de recherche

 actionBar.setCustomView(R.layout.custom_action_bar);
    search = (EditText) actionBar.getCustomView().findViewById(
            R.id.edit_query);

Ensuite, définissez l'option d'affichage pour la barre d'action

actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);

C'est tout. 

Par ailleurs, vous pouvez également utiliser mon search widget qui prend une liste de chaînes sous forme de liste de tableaux et les affiche, en fonction de la requête entrée. Une fois que l'utilisateur a sélectionné un résultat particulier, le résultat sélectionné est renvoyé et peut être récupéré sur le résultat onActivity de l'activité parent. 

0
Riya Gayasen

Ce problème est provoqué par un filtre d'intention manquant:

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