Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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.

@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>
  • Changing namespace of actionViewClass from android:actionViewClass to app:actionViewClass

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

  • 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);
                    If this solved your problem you should probably accept your answer. I would also like to point all the other people with similar problems to one more thread discussing similar issues: stackoverflow.com/q/18407171/1108032. If the current thread does not solve your problems, consider looking into the solutions there.
    – Boris Strandjev
                    Sep 1, 2013 at 11:40
                    Great answer!  It might pay to clarify too that the "app" in app:actionViewClass also requires an additional xmlns declaration for the "app" namespace.
    – jklp
                    Oct 31, 2013 at 1:35
                    Need to say that android.support.v7.widget.SearchView class should not be confused with 'android.support.v4.widget.SearchViewCompat' class (which is known as a common mistake when using ActionBarCompat library)
    – Alex Semeniuk
                    Nov 11, 2013 at 9:38
                    @jklp I try to add xmlns declaration <menu xmlns:app="http://schemas.android.com/apk/res/android" > but get error Attribute is missing the Android namespace prefix. Do you get it, and how do you fix it?
    – anticafe
                    Feb 11, 2014 at 15:30
                    Also note, android:showAsAction needs to be changed to app:showAsAction as well. Also make sure your theme for the activity (not just the application) is referencing an appcompat theme. Last thing, the app declartion is "schemas.android.com/apk/res-auto"
    – Kalel Wade
                    Mar 5, 2014 at 17:23
                    +1. Pretty obvious, but I'll still mention - In case you have extended the SearchView to another class, keep the path to that class in proguard!
    – user2520215
                    Apr 5, 2016 at 14:29
    

    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 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" >
            android:id="@+id/action_search"
            android:icon="@drawable/actionbar_button_search"
            android:title="Search"
            android:showAsAction="always"
            android:actionViewClass="android.widget.SearchView" />
    </menu> 
                    Could you explain why the code sample you provided solves the problem? (I assume it does.)
    – Lone Ronin
                    Jun 23, 2018 at 15:44
    

    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.

    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 did this by manual set in java code:

    <menu xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android">
            android:id="@+id/user_info"
            android:title="@string/user_name_title"
            app:actionLayout="@layout/menu_item_username"
            android:showAsAction="always" />
    </menu>
    

    Layout file:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/usr_name_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:contentDescription="@string/user_info_image_des"
            android:padding="5dp"
            android:paddingStart="10dp"
            android:paddingEnd="10dp"
            android:text="@string/user_name_title"
            android:textStyle="bold"
            android:visibility="visible" />
    </LinearLayout>
    

    Then in java code:

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.connect_menu, menu);
            // show user name on the top of menu
            Log.e("menu", "Size: " + menu.size());
            MenuItem item = menu.getItem(0);
            item.setActionView(R.layout.menu_item_username);
            View v = item.getActionView();
            if (null == v) {
                Log.e("NULL POINTER EX", "NULL MENU VIEW");
            } else {
                TextView usrNameTitle = v.findViewById(R.id.usr_name_title);
                if (null != usrName && usrName.length() > 0) {
                    usrNameTitle.setText(usrName);
            return true;
    

    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.

    This was our issue, we had a mix of android.widget.SearchView in the Activity but had a partial use of v7 in our menu_main.xml file. Just make sure the .xml file is also using app:actionViewClass="android.support.v7.widget.SearchView" too. – gmcc051 Jun 18, 2017 at 3:24 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*
                    To whoever wanted to format the code, this is a very known formatting called "WhiteSmith". Changing to another format doesn't make it better, as this is a matter of taste.
    – android developer
                    Nov 27, 2014 at 13:45
                    @JJD Yes. Correct. It's not as common as others, but I've used it for a very long time. You can set it on Eclipse if you wish.
    – android developer
                    Nov 27, 2014 at 13:53
                    Thanks for sharing. I stay with the default since it avoids a lot unwanted discussions with team members or contributors.
    – JJD
                    Nov 27, 2014 at 14:41
                    @JJD That's also true. at the office we work with a bit different style than the default one. Anyway, a good developer should be able to handle all of the common formatting styles, and if it "hurts the eyes" you can always copy the code and format it on various formatting tools (online, or on the IDE).
    – android developer
                    Nov 27, 2014 at 14:50
    

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

    When I extends ActionBarActivity, it alway return null. But I extends Activity only, it work normal – Hieu Jan 23, 2015 at 19:07 You need to use your own namespace when using ActionBarActivity as it is a part of support library. Since you're using android:showAsAction in your xml it works with Activity (which is not from support library) and doesn't work with ActionBarActivity – Dennis K Apr 20, 2015 at 18:44

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •