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)
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;
}
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 ...
Créer une activité pour gérer les résultats de la recherche
public class Search extends Activity {}
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" />
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>
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>
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 );
}
}
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));
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
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>
).
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.
Ce problème est provoqué par un filtre d'intention manquant:
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
</intent-filter>