MenuItemCompat.getActionView always returns null

折月煮酒 提交于 2019-11-26 08:54:54

问题


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>

回答1:


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



回答2:


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

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



回答3:


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>



回答4:


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> 



回答5:


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.




回答6:


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>



回答7:


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.




回答8:


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*



回答9:


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




回答10:


Remove code: public class DemoActivity extends ActionBarActivity

Replace by: public class DemoActivity extends Activity



来源:https://stackoverflow.com/questions/18438890/menuitemcompat-getactionview-always-returns-null

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