After extending AppCompatActivity instead of Activity, my project is giving the following error:
java.lang.NullPointerException: Attempt to invoke virtual method
'void
android.widget.SearchView.setSearchableInfo(android.app.SearchableInfo)'
on a null object reference
and I followed this link[ this][1] but it did not work for me.
Please give me some suggestions on what I am doing wrong.
This is my code for search:
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
and this is menu xml
<item
android:id="#+id/search"
android:app:actionViewClass="android.widget.SearchView"
android:icon="#drawable/ic_search"
android:app:showAsAction="collapseActionView|always"
android:title="#string/Search"/>
Try using the custom app namespace for your actionViewClass too:
app:actionViewClass="android.support.v7.widget.SearchView"/>
You have to change actionview class of searchview to support and change schema in menu. like this
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/search"
android:title="Search"
android:titleCondensed="false"
android:icon="#drawable/abc_ic_search_api_mtrl_alpha"
android:orderInCategory="0"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
Then in the code you have to get the searchview and use expand listent like this. Remember to use SearchView of support library.
mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchItem);
mSearchView.setQueryHint(mContext.getString(R.string.search_messages));
mSearchView.setIconifiedByDefault(true);
mSearchView.setOnQueryTextListener(this);
MenuItemCompat.setOnActionExpandListener(mSearchItem, new MenuItemCompat.OnActionExpandListener() {
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
}
return true;
}
});
I have the following menu in the main fragment that contains a list:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
app:showAsAction="always|collapseActionView"
android:icon="#android:drawable/ic_menu_search"
android:id="#+id/menu_item_search"
app:actionViewClass="android.widget.SearchView"
android:title="Search"
android:iconifiedByDefault="true"/>
</menu>
It has the necessary setting in the onCreate:
setHasOptionsMenu(true);
Its onCreateOptionsMenu:
getActivity().getMenuInflater().inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu,inflater);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) ((MenuBuilder)menu).getActionItems().get(0).getActionView();
if(searchView!=null)
{
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setSubmitButtonEnabled(false);
searchView.setOnQueryTextListener(this);
}
When I click an item, a new fragment opens and it has a different menu:
<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=".MainActivity">
<item android:id="#+id/action_Save"
android:title="#string/action_Save"
android:orderInCategory="100"
app:showAsAction="always"
android:icon="#android:drawable/ic_menu_save"
/>
</menu>
Its onCreateOptionsMenu:
getActivity().getMenuInflater().inflate(R.menu.menu_fragment_second, menu);
super.onCreateOptionsMenu(menu, inflater);
If I press Back:
if (getFragmentManager().getBackStackEntryCount() > 0)
getFragmentManager().popBackStack();
my first fragment opens and tries to find its SearchView.
It can't find it as the menu of the second fragment is checked and it finds only the Save item.
What should I do to make it work?
You need to call invalidateOptionsMenu() to reset your menu for the fragment.
I had to change how the menuitem was found.
Instead of this:
SearchView searchView = (SearchView) ((MenuBuilder)menu).getActionItems().get(0).getActionView();
I use now this:
SearchView searchView = (SearchView) menu.findItem(R.id.menu_item_search).getActionView();
This way it works.
I am using appcompat v7 for searchview with toolbar except actionbar. below is my menu xml file and java file.
menu file:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
<item
android:id="#+id/action_sort"
android:icon="#drawable/ic_action_sort"
android:title="#string/sort"
app:showAsAction="ifRoom"/>
</menu>
java file:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.dashboard, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
}
return super.onCreateOptionsMenu(menu);
}
now i want to collapse searchview if it is expanded otherwise want to work backpressed on backpressed() method. how can i achieve this.?
Collapsing on backpressed is handled by default in my own setup. I didn't implement a custom onBackPressed method. I did nothing special except extending from ActionBarActivity.
I used MenuItemCompat to get actionview, that might do the trick.
This is my menu xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.yourapp.youractivity">
<item
android:id="#+id/search"
android:title="#string/app_name"
android:icon="#drawable/nav_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
This is how i create the menu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.shop_list, menu);
SearchManager searchManager =
(SearchManager)getSystemService(Context.SEARCH_SERVICE);
//Using MenuItemCompat here, that can do the trick
searchView =
(SearchView)MenuItemCompat.
getActionView(menu.findItem(R.id.search));
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
//etc...
//etc...
return true;
}
In onBackPressed call invalidateOptionsMenu() or store SearchView as Activity field and call searchView.onActionViewCollapsed(); but that can require additional work when restoring your Toolbar state (title state etc.).
Try this inside the Class and extend ActionBarActivity in your Class
(Example: - public class Home extends ActionBarActivity)
#Override
public void onBackPressed() {
super.onBackPressed()
}
For collapsing the SearchView: Try this,
menu.collapseActionView();
(or)
searchView = menuItem.getActionView().
(or)
searchView.onActionViewCollapsed()
I have the code below for searchview implementation. I have written listener code for the searchview to dismiss a fragment, if it is visible. On tap of search icon, fragment gets dismissed correctly, but searchview does not show up, keyboard gets popped up though. On tapping search icon again, serch textview comes.
Is there any obvious issue with the code below. Am I missing something?
Any help is much appreciated
mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
if (null != mSearchView) {
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hideOverLayFragments();
}
});
Code for search menu:
<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.tcs.agilebiz.activities.HomeActivity">
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:checked="true"
android:orderInCategory="103"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search" />
You should initialize your SearchView like this
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
I'm developing an application where the user presses the "Search" icon in the ActionBar and a SearchView is made visible at the top of the screen.
My problem is that the SearchView is not in focus nor expanded so the user has to press the search button on the Searchview to make it expand and bring out the keyboard.
How should this be solved?
You can also call to expandActionView() method in order to force it:
#Override
public boolean onCreateOptionsMenu( Menu menu )
{
super.onCreateOptionsMenu( menu );
MenuItem searchMenuItem = menu.findItem( R.id.mi_search ); // get my MenuItem with placeholder submenu
searchMenuItem.expandActionView(); // Expand the search menu item in order to show by default the query
return true;
}
Search item in the Action Bar layout:
<item
android:id="#+id/mi_search"
android:icon="#drawable/abs__ic_search_api_holo_light"
android:title="#string/search"
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="com.actionbarsherlock.widget.SearchView"
/>
To make the SearchView expanded by default, call setIconifiedByDefault(false) on it when you initialise it (e.g. in onCreateOptionsMenu(..) or onPrepareOptionsMenu(..)). I've found in most cases this will give it focus automatically, but if not simply call requestFocus() on it too.
If you want to have it iconifiedByDefault, this worked for me. setFocusable and setIconified are needed.
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setIconifiedByDefault(true);
searchView.setFocusable(true);
searchView.setIconified(false);
searchView.requestFocusFromTouch();
Update: If you are Using android.support.v7.widget.SearchView the behaviour us very different. clearFocus is needed if you don't want the keyboard pop-up all the time. For some reason the menu is recreated all the time, when using appcompat.
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setIconified(false);
searchView.clearFocus();
If you're using it in layout, you can call
mSearchView.onActionViewExpanded()
This worked for me :
In the root layout :
xmlns:app="http://schemas.android.com/apk/res-auto"
SearchView defined as follows :
<android.support.v7.widget.SearchView
android:id="#+id/search_contacts"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="15dp"
android:background="#drawable/search_view"
app:iconifiedByDefault="false"
app:queryHint="Search name or email"
>
<requestFocus />
</android.support.v7.widget.SearchView>
The difference is with app tag.
app:iconifiedByDefault="false"
app:queryHint="Search name or email"
If you are using inside an activity you need to use
view.onActionViewExpanded();
if you are using inside menu options you need to use
MenuItem.expandActionView();
Note: it works only for SearchView
these two situations are worked for me.
This worked for me:
menu.expandActionView();
You can use the SearchView#setIconified() method on a SearchView handle in your Java code. More here:
http://developer.android.com/reference/android/widget/SearchView.html#setIconified(boolean)
You can also make use of SearchView#setIconifiedByDefault(). More info here:
http://developer.android.com/reference/android/widget/SearchView.html#setIconifiedByDefault(boolean)
use this
SearchManager searchManager = (SearchManager) mActivity.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = new SearchView(mActivity.actionBar.getThemedContext());
searchView.setSearchableInfo(searchManager.getSearchableInfo(mActivity.getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setQueryHint("Search");
menu.findItem(R.id.action_search).setActionView(searchView);
#Pascalius's answer worked for me. But every time you close the SearchView, and click again, you lost the Focus. So I inserted the code in a setOnMenuItemClickListener like this:
MenuItem item = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final SearchView searchView = (SearchView) item.getActionView();
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
searchView.setIconifiedByDefault(true);
searchView.setFocusable(true);
searchView.setIconified(false);
searchView.requestFocusFromTouch();
return false;
}
});
For Appcompat Searchview you can use this method:
MenuItemCompat.expandActionView(mSearchMenuItem);
Kotlin
var searchView = menu.findItem(R.id.action_search).actionView as SearchView
searchView.isIconified = true
Call expandActionView() on the menuItem.
menuItem.expandActionView()
I was having a hard time doing this with SearchView widget, but the expandActionView() method is actually defined in the MenuItem class, not SearchView class. So, I solved it by
MenuItem searchItem = menu.findItem(R.id.item_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchItem.expandActionView();//the method expandActionView is called on searchItem not searchView
MenuItemCompat's SearchView has a property named maxWidth.
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setMaxWidth(xxx);
use screen width instead of xxx offcourse
I am using android.widget Searchview and iconified by default.Below code in xml helped me make it expand and autofocus on search view,when clicked:
<SearchView
android:id="#+id/searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:queryHint="Search"/>
<item
android:id="#+id/search"
android:icon="#drawable/ic_search"
android:title="Search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always"/>
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setQueryHint("Search the customer...");
searchView.setSearchableInfo(Objects.requireNonNull(searchManager).getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setIconifiedByDefault(false);
searchView.requestFocus();
}
<pre>
<item
android:id="#+id/search"
android:icon="#drawable/ic_search"
android:title="Search"
app:actionViewClass="androidx.appcompat.widget.SearchView"
app:showAsAction="always"/>
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setQueryHint("Search the customer...");
searchView.setSearchableInfo(Objects.requireNonNull(searchManager).getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setIconifiedByDefault(false);
searchView.requestFocus();
}
</pre>
android:iconifiedByDefault="true"
Above is the code in XML helped me make it expand and autofocus on search view when clicked: