In an AppCompat activity with context action bar
Trying to add android.support.v7.widget.SearchView to the action mode menu
the searchView doesn't expand
using appcompat-v7:25.2.0
menu Resource file
<?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"
android:icon="#drawable/ic_search_dark_24dp"
android:title="#string/search_list"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always|collapseActionView" />
<item
android:id="#+id/item_two"
android:icon="#drawable/item_two"
android:title="#string/item_two"
app:showAsAction="ifRoom"
>
</item>
</menu>
Activity Theme
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="windowActionModeOverlay">false</item>
<item name="actionModeBackground">#color/colorPrimaryDark</item>
</style>
Activity code
private class SelectionActionModeCallBack implements ActionMode.Callback {
private SearchView mSearchView;
SelectionActionModeCallBack() {
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.book_selection_action_menu, menu);//Inflate the menu over action mode
mSearchView =
(SearchView) menu.findItem(R.id.action_search).getActionView();
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
startSearch(s);
return true;
}
#Override
public boolean onQueryTextChange(String s) {
return false;
}
});
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
mSearchView.requestFocus();
return true;
}
This contradicts the documentation
Contrary to the case when using Search View in action bar the desired collapsible effect for search view while having other items in the action mode
use
app:showAsAction="always"
without collapseActionView !
I am trying to add actions items in my action bar using appcompat. I added search action when I click on it my application crash with NullPointerException. In onCreateOptionsMenu I am getting this view reference but there I am always getting null. Any suggestion to resolve this ??
main.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_bar_refresh"
android:icon="#drawable/ic_action_refresh"
app:showAsAction="ifRoom"
android:title="#string/action_refresh" />
<item
android:id="#+id/action_bar_search"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"
android:title="#string/action_search" />
<item
android:id="#+id/action_bar_settings"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
MainActivity.java
public class MainActivity extends ActionBarActivity {
private SearchView mSearchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_bar_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_bar_search:
mSearchView.setIconified(false);
return true;
}
return false;
}
}
Here I am getting null value in searchView
MenuItem searchItem = menu.findItem(R.id.action_bar_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
Screenshot
<item
android:id="#+id/action_bar_search"
android:icon="#drawable/ic_action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|ifRoom"
android:title="#string/action_search" />
You change showAsAction attribute.
I fixed issue by setting Application Theme to Theme.AppCompat.Light
<style name="AppBaseTheme" parent="#style/Theme.AppCompat.Light">
I'm having a problem with the alignment of the SearchView when it's expanded. For some reason, when collapsed it aligns rights, but when expanded it aligns left. I did everything folowing the ActionBarSherlock examples.
Here are two screenshots of the problem:
Screenshot collapsed http://img59.imageshack.us/img59/8976/.png
Screenshot expanded http://img577.imageshack.us/img577/9890/.png
I have yet to decide if I want to use ActionBar tabs. I don't want the searchView to hide them when expanded. But that's for another question. My main issue here is the alignment of the SearchView when exapanded. I want it to keep the right alignment no matter what.
Here's my onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.menu_main, menu);
searchMenuItem = menu.findItem(R.id.action_search);
refreshMenuItem = menu.findItem(R.id.action_refresh);
refreshMenuItem.setActionView(R.layout.refresh_progressbar);
searchMenuItem.setOnActionExpandListener(new OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
flightsListAdapter.getFilter().filter("");
return true;
}
});
searchView = (SearchView)searchMenuItem.getActionView();
searchView.setQueryHint(getResources().getString(R.string.search_hint));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
searchView.clearFocus();
return true;
}
#Override
public boolean onQueryTextChange(String query) {
flightsListAdapter.getFilter().filter(query);
return true;
}
});
searchView.clearFocus();
return true;
}
And here is my menu_main.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:title="#string/search"
android:icon="#drawable/ic_search"
android:showAsAction="always|collapseActionView"
android:actionViewClass="com.actionbarsherlock.widget.SearchView" />
<item
android:title="#string/date"
android:icon="#drawable/ic_compose"
android:showAsAction="always" >
<menu>
<item
android:id="#+id/menuYesterday"
android:title="Yesterday"/>
<item
android:id="#+id/menuToday"
android:title="Today"/>
<item
android:id="#+id/menuTomorrow"
android:title="Tomorrow"/>
</menu>
</item>
<item
android:id="#+id/action_refresh"
android:icon="#drawable/ic_refresh"
android:showAsAction="always"
android:title="#string/action_refresh" />
</menu>
Thank you for reading :)
Ok. Just for the sake of common knowledge, I'm answering my own question.
The trick was to remove "collapseActionView" on the SerchView. Once I removed that, the SearchView stays in place (to the right) when exanded.
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>
Finally I found the solution.
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);
}
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 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>
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">
<item
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.
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
I am trying to create list search view in shreyaloclistfragment. I am getting NullPointerException at folowing line
final SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
My method is
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater ) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate( R.menu.menu_search, menu);
System.out.println( "inflating menu");
final SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
final SearchView.OnQueryTextListener queryTextListener = new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
showFilteredItems( newText );
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
return;
}
Stack trace
FATAL EXCEPTION: main
java.lang.NullPointerException
at com.sears.syw.FragmentShopsTab.onCreateOptionsMenu(FragmentShopsTab.java:52)
at android.support.v4.app.Watson.onCreatePanelMenu(Watson.java:55)
at
com.actionbarsherlock.ActionBarSherlock.callbackCreateOptionsMenu(ActionBarSherlock.java:559 )
at
com.actionbarsherlock.internal.ActionBarSherlockNative.dispatchCreateOptionsMenu(ActionBarSh erlockNative.java:65)
at
If you are using the Appcompat library, maybe you forgot to add your own xmlns on your menu_search.xml.
As the example says:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
yourapp:showAsAction="ifRoom" />
</menu>
You need to add the folowing:
<item android:id="+#id/..."
android:actionViewClass="android.widget.SearchView"
yourapp:actionViewClass="android.widget.SearchView" />
Source: https://developer.android.com/training/basics/actionbar/adding-buttons.html#XML
If you are using AppCompat library, then in your menu.xml, add
app:actionViewClass="android.support.v7.widget.SearchView"
instead of
app:actionViewClass="android.widget.SearchView"
i am using android studio
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.app.myapp" >
<item
android:id="#+id/search"
android:title="Buscar"
android:icon="#drawable/ic_search"
app:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView"
app:actionViewClass="android.widget.SearchView"/>
</menu>
found 100%
To reference a layout from a menu xml use the actionLayout attribute:
<menu>
<item android:id="#+id/menu_name"
android:actionLayout="#layout/your_layout"
android:showAsAction="always"/>
</menu>
Some times problem is with
setHasOptionsMenu(true);
Move it from oncreate or onviewcreate to on attached method and try it.
Check this answer
Either you are using wrong namespace or importing wrong class
https://stackoverflow.com/a/38702262/5374951