How to add a SearchWidget to the ActionBar?

48,578

Solution 1

use this way as in 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;
    }

Solution 2

Since this question is looked up quite often and I stumbled across the very same problem again and again here is a little follow up that keeps track of all necessary steps to create a SearchWidget.

There is one tricky part about the SearchWidget though: If you use hardcoded Strings in the searchable.xml instead of resources the app will crash with a confusing error message. This took me way too many hours of my life...

  1. Create an Activity to handle the search results

    public class Search extends Activity {}
    
  2. Add a file "searchable.xml" to your res/xml directory (use resources for hint & label!)

    <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. Create the proper menu item "main.xml" in you res/menu directory

    <?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. Update your Manifest.xml: Add the search activity and specify which activities may receive search intents. Adding <meta-data android:name="android.app.default_searchable" android:value=".app.Search" /> to an activity node makes it searchable. Adding it to the application node makes all activities searchable.

    <?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. Add the SearchManager to your ActionView in every activity that should provide the SearchWidget

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

Solution 3

If you are using targeting Android 2.x and using android.support.v7.widget.SearchView check that your menu.xml looks like this (note the 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>

And in the Activity where you inflate the menu use:

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

Solution 4

SearchView getActionView returning null

As in the link, open your menu xml file and change

android:actionViewClass="android.widget.SearchView"

into

app:actionViewClass="android.widget.SearchView" 

this worked for me

Solution 5

I also got the same problem. In my case, change android:actionViewClass to app:actionViewClass solved the problem (with xmlns:app="http://schemas.android.com/apk/res-auto" in <menu> tag).

Share:
48,578

Related videos on Youtube

Taig
Author by

Taig

Updated on September 03, 2020

Comments

  • Taig
    Taig over 3 years

    I'm trying to add a Search-ActionView to my application (as explained here http://developer.android.com/guide/topics/search/search-dialog.html#UsingSearchWidget). Unfortunately I keep getting a NullPointerException and I'm having a hard time detecting what's actually going wrong.

    I created a searchable config and a searchable activity as shown on the android page. My menu .xml file looks like this:

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

    This is the method where the Exception is thrown:

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

    Complete stack trace:

    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)
    
    • rajpara
      rajpara almost 12 years
      can you post whole code ? have you implement searchable configuration and searchable activity as discussed in document ?
    • Taig
      Taig almost 12 years
      As written above: searchable xml and searchable activity are set and added to the Manifest. Line 41 is the one that I commented with "NullPointerException thrown here; searchView is null."
    • Taig
      Taig almost 12 years
      So the problem is actually that menu.findItem(R.id.menu_item_search).getActionView() keeps returning null.
    • Dheeresh Singh
      Dheeresh Singh almost 12 years
      what is the menu file name, as per code R.menu.action_bar, and as per description My menu .xml file looks like this
    • Dheeresh Singh
      Dheeresh Singh almost 12 years
      just confirming as everything else looking fine.....
  • Dheeresh Singh
    Dheeresh Singh almost 12 years
    ok just change the id to menu_item_search_1 to both place then clean & built project and run that ...
  • Dheeresh Singh
    Dheeresh Singh almost 12 years
  • Taig
    Taig almost 12 years
    I didn't figure out what exactly was going wrong but another few tries of renaming, building and cleaning resolved the issue somehow. I probably had some stupid slips somewhere..
  • David Miler
    David Miler over 11 years
    I have tried this solution, but still the searchView in the line searchView.setSearchableInfo(searchManager... is null. How can I get to the actual SearchView as defined in the menu.xml file?
  • blganesh101
    blganesh101 almost 11 years
    Thanks! Really useful answer
  • Tom Kincaid
    Tom Kincaid about 10 years
    Clearest example I've seen
  • Rock Lee
    Rock Lee almost 10 years
    It would help me if step 1 was elaborated; that's the part I'm having trouble with.
  • Saher Ahwal
    Saher Ahwal over 9 years
    This should be marked as the correct answer, the first answer makes no sense it is the searchView that is null not the searchManager.
  • bmeulmeester
    bmeulmeester almost 9 years
    Thanks for the tip. You repaired my current temper.
  • Aubtin Samai
    Aubtin Samai over 7 years
    This doesn't seem to solve the problem, and the code formatting is odd...