Cannot get searchview in actionbar to work

筅森魡賤 提交于 2019-11-26 03:24:55

Your problem is in your AndroidManifest. I had it almost exactly as you do, because that is what I get following the documentation. But it is unclear or mistaken.

Watching at the API Demos source I found that the "android.app.searchable" metadata must go in your "results" activity, and in the main activity (or the activity where you place the SearchView) you point to the other one with "android.app.default_searchable".

You can see it in the following file, which is the Manifest from my test project:

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

It is also important that the hint and label in the searchable.xml are references, and not hardcoded strings.

I hope it solves your problem. It took me all day to figure it out :(

Android guides explicitly says:

// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

Which is in your case NOT TRUE. Because you don't want to search in MainActivity but in SearchableActivity. That means you should use this ComponentName instead of getComponentName() method:

ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));

Also it seems that both the android:hint and android:label attributes MUST be references to strings in strings.xml. Being lazy and hardcoding the string values doesn't seem to work at all :)

i.e. Don't do:

<?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>

But definitely do (as the OP correctly did):

<?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>

If you are using Android Studio,

<meta-data
            android:name="android.app.default_searchable"
            android:value=".SearchActivity" />

part may not work.

write full package name like

<meta-data
                android:name="android.app.default_searchable"
                android:value="com.example.test.SearchActivity" />

be careful with "xml/searchable.xml". If you made HARD CODE with android:hint and android:label.It will not work. Haha Should be :

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/app_name"
android:label="@string/search_lb"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>

There's actually no need use the "missing part" as described in the answers above. This method(using a SearchView) works exactly as the official docs say till Using the Search widget. Here a slight modification needs to made as follows:

Properties in a SearchableInfo are used to display labels, hints, suggestions, create intents for launching search results screens and controlling other affordances such as a voice button(docs).

Thus, the SearchableInfo object we pass to the SearchView.setSearchableInfo(SearchableInfo s) must contain proper references to the target activity which should be displayed to show the search results. This is done by manually passing the ComponentName of our target activity. One constructor for creating a ComponentName is

public ComponentName (String pkg, String cls)

pkg and cls are package names and class names of the target activity to be launched for displaying search results. Note that:

pkg must point to the root package name of your project and,

cls must be a fully qualified name of the class(i.e. the entire thing)

e.g.:

@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;
}

Depending on your requirements take a look at the other ComponentName constructors.

Make sure your searchables.xml file is in the correct location (i.e, in your res/xml/ folder) and that the same file does not contain any errors - otherwise you will find that (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName) will return null, breaking your search functionality.

(Also, ensure you set componentName in the appropriate manner, because the example shown in the Android guide is for only when you are making searches and displaying searches in the same Activity.)

Double check if the corresponding entry(ie search_hint and app_label) is present in values/strings.xml

eg

      <string name="app_label">FunApp</string>
      <string name="search_hint">Caps Off</string>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!