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 list fragment in BaseActivity and want to implement search functionality. but action bar compact height changes while click on search item button
see below screenshot
menu.xml
<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.android.bypeople.uber.BaseActivity" >
<item
android:id="#+id/action_add"
android:icon="#drawable/btn_profile_selector"
android:orderInCategory="100"
android:title="#string/action_add"
android:visible="false"
app:showAsAction="always"/>
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
android:title="#string/action_search"
android:visible="false"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"/>
onCreateOptionsMenu in fragment
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.base, menu);
menu.findItem(R.id.action_add).setVisible(true);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.action_search);
searchItem.setVisible(true);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
searchView.setOnQueryTextListener(queryListener);
queryListener = new OnQueryTextListener() {
#Override
public boolean onQueryTextChange(String newText) {
return false;
}
#Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(getActivity(), "Searching for: " + query + "...", Toast.LENGTH_SHORT).show();
return false;
}
};
}
Refer this link too.!!
resolved issue after lots of search and found something.
may help you too.!!
after add this attribute in toolbar
android:layout_height="?attr/actionBarSize"
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/ToolBarStyle"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/myPrimaryColor"
android:minHeight="#dimen/abc_action_bar_default_height_material" >
<TextView
android:id="#+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/myTextPrimaryColor"
android:layout_gravity="center" />
</android.support.v7.widget.Toolbar>
I am trying to implement a search functionality in my application.
I am trying to display search icon in toolbar, but instead of single search icon multiple icons are getting displayed. One icon is getting displayed from menu.xml file and other icon is getting displayed from the line setHasOptionsMenu(true);.
If I do not use "setHasOptionsMenu(true)" line then onOptionsItemSelectedMenu method will not get called, if I do not give search icon in menu.xml file then search icon will not get displayed. Please let me know how to come out of the issue. I am trying hard with no fruits. Please help me come out of this issue.
My current toolbar looks as shown in the image below:
My menu.xml file:
<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.blo.ifo.ifocusblogs.ActivityForFragments">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
<item android:id="#+id/search"
android:title="#string/search_label"
android:icon="#mipmap/ic_menu_search"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView" />
</menu>
I had the same problem
my problem
and this was the solution that I've found:
add "menu.clear();" to "onPrepareOptionsMenu" in MainActivity
solution
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
getMenuInflater().inflate(R.menu.main,menu);
MenuItem itemSearch = menu.findItem(R.id.action_search);
mSearchView = (SearchView) itemSearch.getActionView();
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSearchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName()));
mSearchView.setQueryHint(getResources().getString(R.string.searchProduct));
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String s) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)){
adapter.getFilter().filter("");
listview.clearTextFilter();
}else {
adapter.getFilter().filter(newText.toString());
}
return true;
}
});
return true;
}
I'm trying to implement SearchView according to some online tutorials. But when i clicked the search icon, it did not expand, instead another search icon appeared to the left and i must click again; this time it worked.
Are there something i'm missing here?
Here are the captured images, sorry i can't post these to stackoverflow yet.
http://1drv.ms/186yI2Y
If i delete collapseActionView then it worked, but i can't customize search icon.
<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/search"
android:title="#string/search_title"
android:icon="#drawable/ic_action_search"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.widget.SearchView"/>
</menu>
In MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
MenuItem searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) searchItem.getActionView();
mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
mSearchView.setIconifiedByDefault(true);
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
showResultsFragment();
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean toggleHandled = mDrawerToggle.onOptionsItemSelected(item);
return toggleHandled || super.onOptionsItemSelected(item);
}
Thank in advance!
in your menu xml i changed app:actionViewClass="android.support.v7.widget.SearchView"
<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/search"
android:title="wrwrwr"
android:icon="#drawable/abc_ic_menu_copy_mtrl_am_alpha"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
and in your activity
import android.support.v7.widget.SearchView; //don't import android.widget.SearchView
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