JakeP
JakeP

Reputation: 1756

Android - NullPointerException on SearchView in Action Bar

I've got a problem trying to add a SearchView widget to the ActionBar in my activity - I get a null value when calling getActionView to get my SearchView object.

I've been following the Android Developer guide and also went through a ton of SO questions as well as some other links on the Internet; all to no avail. It could be something simple but I wasn't able to figure it out - it seems to me my code is basically the same as that from google (apart from changing some names etc.) but it still won't work.

Any help would be appreciated.

Included below are relevant bits of the code. Please let me know if anything's unclear of if you have any idea as to what could possibly be wrong.

Activity code:

    private ListView workflowListView;
    private DrawerLayout drawerLayout;
    private ListView drawerList;
    private ActionBarDrawerToggle drawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
        setContentView(R.layout.activity_workflow_list);

        workflowListView = (ListView) findViewById(R.id.workflowListView);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerList = (ListView) findViewById(R.id.drawer_list);

        drawerToggle = new ActionBarDrawerToggle(
             this,                  /* host Activity */
             drawerLayout,         /* DrawerLayout object */
             R.drawable.ic_launcher,  /* nav drawer icon to replace 'Up' caret */
             R.string.app_name,  /* "open drawer" description */
             R.string.app_name  /* "close drawer" description */
             ) {

                /** Called when a drawer has settled in a completely closed state. */
                public void onDrawerClosed(View view) {
    //                getActionBar().setTitle("Closed drawer");
                }

                /** Called when a drawer has settled in a completely open state. */
                public void onDrawerOpened(View drawerView) {
    //                getActionBar().setTitle("Open drawer");
                }
       };

       drawerLayout.setDrawerListener(drawerToggle);
       ActionBar actionBar = getActionBar();
       actionBar.setDisplayShowTitleEnabled(false);

       actionBar.setDisplayHomeAsUpEnabled(true);
       actionBar.setHomeButtonEnabled(true);
       actionBar.setIcon(android.R.color.transparent);

       String[] testData = {"a", "b", "c", "d"};
       ArrayList<String> workflowList = new ArrayList<String>();
           for (String s : testData) {

                workflowList.add(s);
           }

       ArrayAdapter<String> workflowAdapter = new ArrayAdapter<String>(this.getApplicationContext(), R.layout.workflow_list_item, workflowList);

            workflowListView.setAdapter(workflowAdapter);
   }


   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
   // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.workflow_list, menu);
        inflater.inflate(R.menu.options_menu, menu);

        // Associate searchable configuration with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        // The below line returned null even though it was used in Google sample code
        SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();

        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

        return super.onCreateOptionsMenu(menu);
    }

xml/searchable.xml:

<?xml version="1.0" encoding="utf-8"?>

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="@string/search_hint"
        android:includeInGlobalSearch="false" />

menu/options_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:app="http://schemas.android.com/apk/res-auto" >

    <item android:id="@+id/search"
          android:title="@string/search_title"
          android:icon="@drawable/ic_action_search"
          android:showAsAction="always|collapseActionView"
          android:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

Upvotes: 48

Views: 22805

Answers (8)

liang
liang

Reputation: 1

for me, This is the right answer: In menu/options_menu.xml, use this:

app:actionViewClass="android.support.v7.widget.SearchView"

Upvotes: 0

ketankk
ketankk

Reputation: 2664

First check you are using app namespace for actionViewClass.

android:actionViewClass="android.support.v7.widget.SearchView"-this throws NPE

app:actionViewClass="android.support.v7.widget.SearchView"-use this

and second

Check if you are using same searchView in menu.xml and in your Activity

Upvotes: 25

Jacob
Jacob

Reputation: 588

For anyone still searching, I followed everything above and could not seem to get things going. I wrapped my searchView.setSearchableInfo... in a null check and voila! It ran just like it ought to.

if (searchView != null) {
    searchView.setSearchableInfo(searchManager.getSearchableInfo(
                    new ComponentName(getApplicationContext(), SearchActivity.class)));
}

Upvotes: 0

waynesford
waynesford

Reputation: 1698

I had a similar probably that appeared on my release builds but not my debug builds when switching over to the v21 support library. Turned out to be an obfuscation problem, and adding this line to my proguard-rules.txt file fixed it:

-keep class android.support.v7.widget.SearchView { *; }

Upvotes: 25

Parampal Pooni
Parampal Pooni

Reputation: 3108

I had a very similar issue where the following line was returning null

SearchView searchView = (android.support.v7.widget.SearchView)MenuItemCompat.getActionView(searchMenuItem);

The fix was in my styles.xml file, i changed my AppTheme's parent to Theme.AppCompat.Light

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light">

Upvotes: 1

steving21
steving21

Reputation: 1

I think you're occupying FragmentActivity, you need to extend of ActionBarActivity

Upvotes: -1

Szymon
Szymon

Reputation: 43023

Try to replace the failing line with:

mSearchMenuItem = menu.findItem(R.id.action_search);
mSearchView = (EnglishVerbSearchView) MenuItemCompat.getActionView(mSearchMenuItem);

Where R.id.action_search is the id of your search item in the menu.

EDIT

Your manifest should look like that:

<activity
       android:name="com.bronzelabs.twc.activities.WorkflowListActivity"
       android:label="@string/app_name"
       android:theme="@style/Theme.AppCompat.Light" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>
<activity 
        android:name=".activities.SearchResultActivity"
        android:theme="@style/Theme.AppCompat.Light"
        android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable" android:resource="@xml/searchable"
            android:value=".activities.SearchResultActivity" />
    </activity>

The way you call setSearchableInfo is:

mSearchView.setSearchableInfo(searchManager.getSearchableInfo(
            new ComponentName(getApplicationContext(), SearchResultActivity.class)));

EDIT 2

Make sure your menu xml file is like that (pay attention to those 2 attributes with yourapp namespace - this is needed when you use the compat library):

<menu xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
    <item android:id="@+id/action_search"
      android:title="@string/action_search"
      android:icon="@drawable/action_search"
      yourapp:showAsAction="always|collapseActionView"
      yourapp:actionViewClass="android.support.v7.widget.SearchView" />
</menu>

Upvotes: 107

Hans
Hans

Reputation: 521

I had the same problem. My solution is: replace android:actionViewClass="android.support.v7.widget.SearchView" with

android:actionViewClass="android.widget.SearchView"

Upvotes: -2

Related Questions