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);
–
–
–
–
–
–
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>
–
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.
–
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)"
–
–
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.