Je suis assez nouveau pour Java et Android; et je travaille sur une application dans laquelle je veux une barre d'action avec un SearchView
. J'ai regardé les exemples de google mais je n'arrive pas à le faire fonctionner. Je dois faire quelque chose de mal et je suis sur le point d'abandonner le développement d'applications: DI a cherché mais je n'ai rien trouvé d'utile. Peut-être que vous les gars peuvent m'aider :)
Le problème : je fais ouvrir la vue de recherche comme il se doit, mais après cela rien ne se passe du tout, j'ai remarqué que mon searchManager.getSearchableInfo (getComponentName ()) renvoie null. De plus, mon indice que j'ai donné ne s'affiche pas dans ma zone de recherche, ce qui m'amène à croire que l'application ne trouve peut-être pas mon fichier de recherche.xml? Assez parlé :)
MainActivity.Java
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}
}
consultable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/search_hint"
Android:label="@string/app_label">
</searchable>
Manifeste Android
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.searchapp"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="14"
Android:targetSdkVersion="15" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme" >
<activity Android:name=".SearchableActivity" >
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
</intent-filter>
</activity>
<activity
Android:name=".MainActivity"
Android:label="@string/title_activity_main" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data Android:name="Android.app.searchable"
Android:resource="@xml/searchable"/>
</application>
</manifest>
SearchableActivity.Java
package com.example.searchapp;
import Android.app.ListActivity;
import Android.app.SearchManager;
import Android.content.Intent;
import Android.os.Bundle;
import Android.util.Log;
public class SearchableActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doMySearch(query);
}
}
private void doMySearch(String query) {
Log.d("Event",query);
}
}
Et voici un lien vers le projet référé, je serais éternellement reconnaissant si quelqu'un devait m'aider avec ça!
Votre problème est dans votre AndroidManifest. Je l'avais presque exactement comme vous, car c'est ce que j'obtiens en suivant la documentation. Mais ce n'est pas clair ou c'est faux.
En regardant la source des démonstrations d'API, j'ai constaté que les métadonnées "Android.app.searchable" doivent aller dans votre activité "résultats", et dans l'activité principale (ou l'activité où vous placez le SearchView) vous pointez sur l'autre avec " Android.app.default_searchable ".
Vous pouvez le voir dans le fichier suivant, qui est le manifeste de mon projet de test:
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.example.test"
Android:versionCode="1"
Android:versionName="1.0" >
<uses-sdk
Android:minSdkVersion="8"
Android:targetSdkVersion="15" />
<application
Android:icon="@drawable/ic_launcher"
Android:label="@string/app_name"
Android:theme="@style/AppTheme" >
<activity
Android:name=".MainActivity"
Android:label="@string/title_activity_main" >
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
Android:name="Android.app.default_searchable"
Android:value=".SearchActivity" />
</activity>
<activity
Android:name=".SearchActivity"
Android:label="@string/app_name" >
<!-- This intent-filter identifies this activity as "searchable" -->
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
<!-- This metadata entry provides further configuration details for searches -->
<!-- that are handled by this activity. -->
<meta-data
Android:name="Android.app.searchable"
Android:resource="@xml/searchable" />
</activity>
</application>
Il est également important que l'indicateur et l'étiquette dans le fichier searchable.xml soient des références et non des chaînes codées en dur.
J'espère que cela résout votre problème. Il m'a fallu toute la journée pour le comprendre :(
Les guides Android disent explicitement:
// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
Ce qui est dans votre cas PAS VRAI. Parce que vous ne voulez pas rechercher dans MainActivity mais dans SearchableActivity. Cela signifie que vous devez utiliser ce ComponentName au lieu de la méthode getComponentName ():
ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));
Il semble également que les attributs Android: hint et Android: label DOIVENT être des références à des chaînes dans strings.xml. Être paresseux et coder en dur les valeurs de chaîne ne semble pas fonctionner du tout :)
c'est-à-dire ne pas faire:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="Search for something..."
Android:label="My App">
</searchable>
Mais certainement (comme l'OP l'a fait correctement):
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/search_hint"
Android:label="@string/app_label">
</searchable>
Si vous utilisez Android Studio,
<meta-data
Android:name="Android.app.default_searchable"
Android:value=".SearchActivity" />
une partie peut ne pas fonctionner.
écrire le nom complet du package comme
<meta-data
Android:name="Android.app.default_searchable"
Android:value="com.example.test.SearchActivity" />
soyez prudent avec "xml/searchable.xml". Si vous avez créé HARD CODE avec Android:hint
et Android:label
.Ça ne marchera pas. Haha devrait être:
<searchable xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:hint="@string/app_name"
Android:label="@string/search_lb"
Android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>
Assurez-vous que votre searchables.xml
le fichier est au bon endroit (c'est-à-dire dans votre res/xml/
dossier) et que le même fichier ne contient aucune erreur - sinon vous constaterez que (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
renverra null, brisant votre fonctionnalité de recherche.
(Assurez-vous également que vous définissez componentName
de la manière appropriée, car l'exemple illustré dans le guide Android est destiné uniquement lorsque vous effectuez des recherches et affichez des recherches dans la même activité). )
Il n'est en fait pas nécessaire d'utiliser la "partie manquante" comme décrit dans les réponses ci-dessus. Cette méthode (en utilisant un SearchView
) fonctionne exactement comme le disent les documents officiels jusqu'à en utilisant le widget de recherche . Ici, une légère modification doit être effectuée comme suit:
Les propriétés d'un SearchableInfo
sont utilisées pour afficher des étiquettes, des conseils, des suggestions, créer des intentions pour lancer des écrans de résultats de recherche et contrôler d'autres options telles qu'un bouton vocal ( docs ).
Ainsi, l'objet SearchableInfo
que nous transmettons à la fonction SearchView.setSearchableInfo(SearchableInfo s)
doit contenir des références appropriées à l'activité cible qui doit être affichée pour afficher les résultats de la recherche. Cela se fait en passant manuellement le ComponentName
de notre activité cible. Un constructeur pour créer un ComponentName
est
public ComponentName (String pkg, String cls)
pkg
et cls
sont les noms de package et les noms de classe de l'activité cible à lancer pour afficher les résultats de la recherche. Notez que:
pkg
doit pointer vers le nom du package racine de votre projet et,
cls
doit être un nom complet de la classe (c.-à-d. le tout)
par exemple.:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
// Get the SearchView and set the searchable configuration
String pkg = "com.example.musicapp"
String cls = "com.example.musicapp.search.SearchActivity"
ComponentName mycomponent = new ComponentName(pkg,cls);
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mycomponent));
searchView.setIconifiedByDefault(false); //if using on actionbar
return true;
}
En fonction de vos besoins, jetez un œil aux autres constructeurs ComponentName
.