SearchView (Support) in FragmentActivity always null - android

I've started messing around with fragments, as my app on tablets could be using space more efficiently.
Now, in my old app, I had a SearchView in the actionbar menu, that would show on ifRoom. I'm using the same code, but now the SearchView item is always null. I'm not looking for changing the menu items depending on active fragments or whatever, I just need the SearchView to function from the FragmentActivity.
FragmentActivity:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.svPet);
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
if(this.svPet != null)
{
this.svPet.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
this.svPet.setOnQueryTextListener(this);
}
return true;
}
main.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/svPet"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"
android:title="#string/search"
android:titleCondensed="#string/search">
</item>
...Some more items that are never shown as action and work correctly
</menu>
So, whenever the menu is being created, this.svPet stays null, the searchview is not displayed in the bar (even when there's more than enough room), and when I click on the item from the menu, my application crashes, saying there's a nullpointer on
this.svPet.setIconified(false);
in
#Override
public boolean onOptionsItemSelected(MenuItem item)
Any ideas on what might be wrong? I'm probably overlooking something, but I just don't see what's wrong at the moment. Thanks in advance :)

some ideas
#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
<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>

So... after some digging I found that when using MenuItemCompat in combination with FragmentActivity, getActionView(searchItem) returns null. I think this is a bug in the support library, so I'll have to submit a bugreport for that. (Done, https://code.google.com/p/android/issues/detail?id=76141&thanks=76141&ts=1410649918)
My workaround:
Instead of
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
I used
this.svPet = new SearchView(this);
MenuItemCompat.setShowAsAction(searchItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(searchItem, this.svPet);
--Edit--
After some more looking around, I found that you can just use ActionBarActivity instead of FragmentActivity, as ActionBarActivity extends FragmentActivity. When using that, you can use
this.svPet = (SearchView)MenuItemCompat.getActionView(searchItem);
as usual.

Related

Android Options Menu on Action bar shows duplicate icons

action bar (Toolbar) on android has 3 options menu. Its working fine. But the problem is when ever i am uninstalling and reinstalling this duplication of the menu item is showing. Also the Title is also remains same, not changing. after sometimes, say if we close the app and restarts its working fine. I am totally confused and struck.
Here is the Code, MainActivity (OnCreateOptionsMenu):
#Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.clear();
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) MainActivity.this.getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = null;
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(MainActivity.this.getComponentName()));
}
MenuItem item = menu.findItem(R.id.action_wishlist);
wishlistCount = (RelativeLayout) MenuItemCompat.getActionView(item);
wishlistCount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
setWishlistCount();
MenuItem cartitem = menu.findItem(R.id.action_cart);
cartCount = (RelativeLayout) MenuItemCompat.getActionView(cartitem);
cartCount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
restoreToolbar();
return super.onCreateOptionsMenu(menu);
}
Here is my menu_main.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">
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="always"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>
<item
android:id="#+id/action_wishlist"
android:orderInCategory="300"
android:title="#string/wishlist"
app:actionLayout="#layout/actionbar_badge_layout"
android:icon="#drawable/ic_wishlist_dark"
app:showAsAction="always"></item>
<item
android:id="#+id/action_cart"
android:orderInCategory="300"
android:title="#string/cart"
app:actionLayout="#layout/actionbar_badge_cart_layout"
android:icon="#drawable/ic_cart_dark"
app:showAsAction="always"></item>
</menu>
Here is the Screenshot:
1: first time:
enter image description here
2: normal:
enter image description here
Note: The problem occurs when the application opens with opening navigation bar, else its working fine. On createoptionsmenu is called at all times, but still its not working. Anyone can help on this?
More Precisely this should do the trick:
menu.clear() and return super.onCreateOptionsMenu(menu); does the trick! :)
#Override
public boolean onPrepareOptionsMenu(final Menu menu)
{
menu.clear();
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, menu);
return super.onCreateOptionsMenu(menu);
}
CHEERS! :)
I have cleared it by myself, by changing the code from "onCreateOptionsMenu" to "OnPrepareOptionsMenu". Also it is recommended to call Super class before clearing or inflating the menu.
Thanks for all.

getActionView returns null with searchview

Trying to get searchview to work on app.
sdk min 17 max 22
testing on emulator api 18
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_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never"/>
<item android:id="#+id/search"
android:icon="#drawable/ic_action_search"
android:title="#string/search_title"
app:showAsAction="ifRoom|collapseActionView"
android:orderInCategory="200"
app:actionViewClass="android.support.v7.widget.SearchView">
</item>
<item android:id="#+id/scan"
android:title="#string/scan"
android:showAsAction="ifRoom"
android:orderInCategory="300">
</item>
</menu>
onCreateOptionsMenu
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.material_toolbar, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
Log.d(TAG, "onQueryTextSubmit");
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
materialUpdate();
return false;
}
});
}
Running debug and looking at the search menu item shows action as null.
The layout display shows the android.support.v7.widget.SearchView as unknown xml attribute.
I am using Eclipse instead of Android Studio on this project.
Are you using Proguard or minify(ing) your code at some way?
https://code.google.com/p/android/issues/detail?id=58508
When you use a minify method like Proguard, classes and methods that you not access directly (but by some declarative way or reflexion) are removed. To avoid this, you need to instruct the build to specifically keep this classes/methods.
In this case, the SearchView class can be removed, because isn't directly called.
Try add this on your proguard rules file (check the right filename on your gradle file, at getDefaultProguardFile):
-keep class android.support.v7.widget.SearchView { *; }
This is how I added a SearchView to my menu (this is inside a Fragment):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
final SearchView searchView = new SearchView(getActivity());
searchView.setOnQueryTextListener(this);
searchView.setIconifiedByDefault(true);
item.setActionView(mSearchView);
}
As an aside, I'd also recommend making the switch to Android Studio.
You are using support library. Try this:
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.menu_search));
// ...
return true;
}
Not sure exactly what was wrong with what I had. It all appeared to be logical. I suspect that I had some misspelling are xmlns that was not correct. But it works the way I have it.
I appreciate the help but recommend that answers explain what you believe the problem is, what the fix is and why. It really helps the person learn.
MenuItemCompat is helper for accessing features in MenuItem introduced after API level 4 in a backwards compatible fashion. It is not necessary for this scenario.
Please keep answering questions it really does help
Thanks

Search button in toolbar for fragment is not displaying keyboard

I have multiple fragments in an activity where I want a search button in the toolbar. In one of my fragments this all successfully works but when I copied the exact same code into my other two fragments they aren't functioning properly.
When I click the search button on the working fragment, the keyboard pops up and I can start entering text. But on the other two fragments when I press on the search button icon, it slides to the left and then I need to press it again for it to work. Anyone know how I can fix this?
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.search, menu);
MenuItem item = menu.findItem(R.id.action_search);
SearchView sv = new SearchView(((Home) getActivity()).getSupportActionBar().getThemedContext());
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, sv);
sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
list.clear();
for (int i = 0; i < mainList.size(); i++) {
if (mainList.get(i).getName().toLowerCase().startsWith(newText.toLowerCase(), 0) || mainList.get(i).getAddress().toLowerCase().startsWith(newText.toLowerCase())) {
list.add(mainList.get(i));
}
}
adapter.notifyDataSetChanged();
return false;
}
});
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case R.id.action_search:
getActivity().onSearchRequested();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Try to define searchView in menu item.
<item android:id="#+id/action_search"
android:icon="#drawable/ic_search_white_24dp"
android:title="#string/search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="collapseActionView|always" />
Hey i have same issue and i found solution for it. it may be because of you are giving a whole menu for search view. so when you click first time on search icon that full menu gets load and then you again click on search icon and then search view gets open.
Try below code
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
inflater.inflate(R.menu.searchview, menu);
MenuItem item = menu.findItem(R.id.menu_item_search);
SearchView sv = (SearchView) item.getActionView();
if (sv != null){
sv.setSubmitButtonEnabled(true);
sv.setOnQueryTextListener(this);
}
super.onCreateOptionsMenu(menu, inflater);
}
searchview.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
app:showAsAction="always|collapseActionView"
android:icon="#android:drawable/ic_menu_search"
android:id="#+id/menu_item_search"
android:orderInCategory="1"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"
android:iconifiedByDefault="true"/>
</menu>
And make sure you import android.support.v7.widget.SearchView otherwise it will give error in casting.
Hope it will help.

android collapsable searchview with custom header

I need the suggestion for using the best way to show searchview with custom header.
My headerlayout should initially look like this
And after clicking the search button on the right of the header, it must replace header title and menu icon part with the search input field like this.
pressing back in this state, should direct to initial state.
How can I do this?
in Menu Resource directory
search_country_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"
android:icon="#drawable/abc_ic_search"
app:showAsAction="always|collapseActionView"
android:orderInCategory="0"
app:actionViewClass="android.support.v7.widget.SearchView"/>
</menu>
**In Activity's onCreateOptionmenu Method **
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.search_country_menu, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
menu.findItem(R.id.action_search).expandActionView();
searchView.setQueryHint(getResources().getString(R.string.select_country));
searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);
searchView.setOnQueryTextListener(new OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String arg0) {
searchView.clearFocus();
return true;
}
#Override
public boolean onQueryTextChange(String arg0) {
etSearch.setText(arg0);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
Do you want to customize the SearchViewor is a standard one fine for you?
If it is I suggest looking into the ActionBar with an ActionView
Android ActionBar documentation about adding an ActionView

Multiple searchable activities with suggestions

I have app with 2 activities - 2 different listviews with different data and I would like to have searching via actionbar in both. Also, both should contain suggestions support.
So far, it seems that I can have only one searchable.xml that is always bound to only one activity:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_name"
android:hint="#string/search_hint"
android:searchSuggestAuthority="XXXSuggestionsContentProvider"
android:searchSuggestIntentAction="android.intent.action.VIEW">
</searchable>
Is there a way I can have multiple searchables?
Thanks.
You can try this, works just perfectly for me.
Inflate menu like this in activity.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String text) {
//REFRESH ADAPTER WITH NEW FILTERED LIST HERE
return false;
}
#Override
public boolean onQueryTextChange(String text) {
//REFRESH ADAPTER WITH NEW FILTERED LIST HERE
return false;
}
});
return true;
}
Menu should look something like this for it to work:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grupete="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_search"
android:icon="#android:drawable/ic_menu_search"
grupete:actionViewClass="android.support.v7.widget.SearchView"
android:orderInCategory="100"
android:title="#string/search"
grupete:showAsAction="ifRoom"/>
</menu>
Hope I could help you!
Best regards,
pedrovic90

Categories

Resources