MenuItemCompat.getActionView always returns null

I just implemented the v7 AppCompat support library but the MenuItemCompat.getActionView always return null in every Android version I tested (4.2.2, 2.3.4 ….)

The SearchView is displayed in action bar but it doesn’t respond to touch actions and doesn’t expand to show its EditText and is just like a simple icon.

  • Does the android web browser allow uploading photos just taken from camera?
  • Error : Failed to find: com.android.support:support-v4:20.0.+
  • Outdated Kotlin Runtime warning (Kotlin plugin 1.1.2-release-Studio2.3-3)
  • Android View align bottom (programmatically) without XML
  • Android:Passing a hash map between Activities
  • How to get current playing song details from MediaPlayer
  • @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
    
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        if (searchView != null) {
            SearchViewCompat.setOnQueryTextListener(searchView, mOnQueryTextListener);
            searchView.setIconifiedByDefault(false);
            Log.d(TAG,"SearchView not null");
        } else
            Log.d(TAG, "SearchView is null");
        }
        return super.onCreateOptionsMenu(menu);
    }
    

    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/action_search"
              app:showAsAction="always|collapseActionView"
              android:icon="@drawable/abc_ic_search"
              android:title="@string/action_bar_search"
              android:actionViewClass="android.support.v7.widget.SearchView"/>
    
        <item android:id="@+id/action_refresh"
              android:icon="@drawable/refresh"
              android:title="@string/action_bar_refresh"
              app:showAsAction="ifRoom"/>
    </menu>
    

  • How to Verify whether bluetooth headsets are connected on Android?
  • Questions about preparing an apk for the Amazon Android App Store
  • How to add source + javadoc for android-support-v7?
  • Get the pushed ID for specific value in firebase android
  • com.android.ddmlib.SyncException: Too many open files
  • Android Toolbar: small title text in landscape mode
  • 10 Solutions collect form web for “MenuItemCompat.getActionView always returns null”

    Finally I found the solution.

    1. Changing namespace of actionViewClass from android:actionViewClass to app:actionViewClass

    2. Implementing android.support.v7.widget.SearchView.OnQueryTextListener interface for current activity.

    3. Directly use setOnQueryTextListener instead of SearchViewCompat.setOnQueryTextListener

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
      
        MenuItem searchItem = menu.findItem(R.id.action_search);
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
        if (searchView != null) {
           searchView.setOnQueryTextListener(this);
        }
      
        return super.onCreateOptionsMenu(menu);
      }
      

    In my case it was ProGuard file. You need to add this line:

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

    For me, an incorrect menu.xml namespace import caused this problem.

    My original menu.xml:

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/tools">
            <item android:id="@+id/action_search"
                  android:title="@string/map_option_search"
                  android:icon="@drawable/ic_action_search"
                  app:showAsAction="collapseActionView|ifRoom"
                  app:actionViewClass="android.support.v7.widget.SearchView"/>
    </menu>
    

    It looks like the xmlns:app="http://schemas.android.com/tools" was causing MenuItemCompat.getActionView() to return null. Changing this import to xmlns:app="http://schemas.android.com/apk/res-auto" fixed the problem.

    New working menu.xml:

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

    I was with the same error, my method getActionView() was always returning null. So, I’ve made the following things:

    <item android:id="@+id/action_search"
          android:icon="@drawable/abc_ic_search"
          android:title="@string/search_title"
          android:showAsAction="always"
          android:actionViewClass="android.widget.SearchView"/>
    

    I saw in some posts that the people are using app: or yourapp, but i’ve used normally android:ActionVewClass.

    On my onCreateOptionsMenu method:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.feed, menu);
    
        // Associate searchable configuration with the SearchView
        SearchManager searchManager = 
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
                .getActionView();
        searchView.setSearchableInfo(searchManager
                .getSearchableInfo(getComponentName()));
    
        return true;
    }
    

    And do not forget to put in the onCreate method:

    // enabling action bar app icon and behaving it as toggle button
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);
    

    This works very well for my activity “extending” for FragmentActivity and ActionBarActivity.

    I think that the problem is that you use the SearchView from the Support V7 package and maybe your API level is set to…..22??.

    Changing your code to the following in order to fix the problem:

    menu.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item 
            android:id="@+id/action_search"
            android:icon="@drawable/actionbar_button_search"
            android:title="Search"
            android:showAsAction="always"
            android:actionViewClass="android.widget.SearchView" />
    </menu> 
    

    Mohsen Afshin’s answer above was my starting point and I made some tweaks to get it working with my setup:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu, menu);
        MenuItem searchItem = menu.findItem(R.id.action_search);
        // SearchView searchView = (SearchView) MenuItemCompat
        //    .getActionView(searchItem);
        SearchView searchView = (SearchView) searchItem.getActionView();
        if (searchView != null) {
            searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String s) {
                    // do something with s, the entered string
                    query = s;
                    Toast.makeText(getApplicationContext(), 
                        "String entered is " + s, Toast.LENGTH_SHORT).show();
                    return true;
                }
                @Override
                public boolean onQueryTextChange(String s) {
                    return false;
                }
            });
        }
        return super.onCreateOptionsMenu(menu);
    }
    

    menu.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".MainActivity" >
    
    <item android:id="@+id/action_search"
        android:orderInCategory="5"
        android:title="Search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="ifRoom|collapseActionView"
        android:actionViewClass="android.widget.SearchView" />
    </menu>
    

    I had the same code, but instead of using the import android.support.v7.widget.SearchView; I was using import android.widget.SearchView; . This fixed my problem with the null value.
    So just change this code in your search activity and it will work and also change the namespace in xml file.

    Here’s a snippet of how to handle the searchView from support library v7 :

    @Override
    public void onCreateOptionsMenu(final Menu menu,final MenuInflater inflater)
      {
      menu.clear();
      getActivity().getMenuInflater().inflate(...,menu);
      _searchView=(SearchView)MenuItemCompat.getActionView(_searchMenuItem);
      _searchView.setQueryHint(...);
    
      if(VERSION.SDK_INT<VERSION_CODES.HONEYCOMB)
        {
        final EditText searchTextView=(EditText)searchView.findViewById(R.id.search_src_text);
        if(searchTextView!=null)
          {
          searchTextView.setScroller(new Scroller(_context));
          searchTextView.setMaxLines(1);
          searchTextView.setVerticalScrollBarEnabled(true);
          searchTextView.setMovementMethod(new ScrollingMovementMethod());
          searchTextView.setTextColor(_context.getResources().getColor(App.getResIdFromAttribute(_context,android.R.attr.textColorPrimary)));
          }
        }
      _searchView.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener()
        {
        ...
        });
      MenuItemCompat.setActionView(_searchMenuItem,_searchView);
      MenuItemCompat.setOnActionExpandListener(_searchMenuItem,new OnActionExpandListener()
        {
        ...
        });
      super.onCreateOptionsMenu(menu,inflater);
      }
    
    
    public static int getResIdFromAttribute(final Activity activity,final int attr)
      {
      if(attr==0)
        return 0;
      final TypedValue typedvalueattr=new TypedValue();
      activity.getTheme().resolveAttribute(attr,typedvalueattr,true);
      return typedvalueattr.resourceId;
      }
    

    Also, if you use Proguard, add this to its configuration :

    -keep class android.support.v4.app.** { *; }
    -keep interface android.support.v4.app.** { *; }
    -keep class android.support.v7.widget.SearchView { *; }
    -keepattributes *Annotation*
    

    I had a very similar issue with the difference being I was attempting to use a class that extended android.widget.ImageView

    If you’re using ProGuard, you need to specify to allow the methods involved in this class.

    -keep public class * extends android.widget.ImageView{
      public <init>(android.content.Context);
      public <init>(android.content.Context, android.util.AttributeSet);
      public <init>(android.content.Context, android.util.AttributeSet, int);
      public void set*(...);
    }
    

    http://proguard.sourceforge.net/manual/examples.html

    This says, “Allow all needed constructors that might be called from xml and allow any custom setters it uses as well (add more as needed)”

    Remove code:
    public class DemoActivity extends ActionBarActivity

    Replace by:
    public class DemoActivity extends Activity

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.