i have a FragmentActivity (support-v4) with two Fragments. And both contains a menu with a SearchView for the ActionBar.
PlaylistFragment:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(LOGTAG, String.format("onCreateOptionsMenu(%s,%s)", this, menu));
inflater.inflate(R.menu.playlist_ab_menu, menu);
buildLocalSearchView(menu.findItem(R.id.menu_playlist_search));
super.onCreateOptionsMenu(menu, inflater);
}
private void buildLocalSearchView(MenuItem item) {
SearchView searchView = (SearchView) item.getActionView();
searchView.setSubmitButtonEnabled(false);
searchView.setIconifiedByDefault(true);
searchView.setIconified(true);
//don't work because a bug in android, @see https://code.google.com/p/android/issues/detail?id=25758
searchView.setOnCloseListener(this);
//workaround for the above
MenuItemCompat.setOnActionExpandListener(item, new MenuItemCompat.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(MenuItem item) {
return true;
}
});
searchView.setOnQueryTextListener(adapter);
}
and similar for the FilterlistFragment:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(LOGTAG, String.format("onCreateOptionsMenu(%s,%s)", this, menu));
inflater.inflate(R.menu.filterlist_ab_menu, menu);
// Get the SearchView and set the searchable configuration
buildLocalSearchView(menu.findItem(R.id.menu_filterlist_search));
super.onCreateOptionsMenu(menu, inflater);
}
but if i now start a search in the FilterlistFragment and don't close the SearchView but switch to the PlaylistFragment, the query-string was transfered from FilterlistFragment to PlaylistFragment. But the ActionBar-SearchView was visible like closed in the PlaylistFragment.
I can see in my Log after switch to the PlaylistFragment:
07-25 05:09:29.277 3315-3315/de.NullZero.ManiDroid D/de.NullZero.ManiDroid.presentation.fragments.FilterListFragment﹕ onDestroyView(FilterListFragment{b12b8090 #2 id=0x7f0a0085 FILTER_2})
07-25 05:09:29.277 3315-3315/de.NullZero.ManiDroid D/PlaylistFragment﹕ onCreate(PlaylistFragment{b13dcc58 #3 id=0x7f0a0085 PLAYLIST},null)
07-25 05:09:29.277 3315-3315/de.NullZero.ManiDroid D/PlaylistFragment﹕ onViewCreated(PlaylistFragment{b13dcc58 #3 id=0x7f0a0085 PLAYLIST},null)
07-25 05:09:29.277 3315-3315/de.NullZero.ManiDroid D/de.NullZero.ManiDroid.presentation.ManiDroidAppActivity﹕ onBackStackChanged() Fragment:PlaylistFragment{b13dcc58 #3 id=0x7f0a0085 PLAYLIST}
07-25 05:09:29.287 3315-3360/de.NullZero.ManiDroid D/DEBUG﹕ searchInPlaylist() = 2 ms
07-25 05:09:29.307 3315-3315/de.NullZero.ManiDroid D/PlaylistFragment﹕ onCreateOptionsMenu(PlaylistFragment{b13dcc58 #3 id=0x7f0a0085 PLAYLIST},com.android.internal.view.menu.MenuBuilder@b106ad90)
07-25 05:09:29.317 3315-3315/de.NullZero.ManiDroid D/PlaylistFragment﹕ onPrepareOptionsMenu(PlaylistFragment{b13dcc58 #3 id=0x7f0a0085 PLAYLIST},com.android.internal.view.menu.MenuBuilder@b106ad90)
07-25 05:09:29.477 3315-3364/de.NullZero.ManiDroid D/DEBUG﹕ searchInFilter(, ManitobaFilter{filterName='Zuletzt gehört'}) = 178 ms
07-25 05:09:29.477 3315-3364/de.NullZero.ManiDroid D/DEBUG﹕ searchInPlaylist(max) = 1 ms
the searchInPlaylist() method was the SearchView (adapter) method for the PlaylistFragment and the searchInFilter(...) the one for the FilterlistFragment.
And as you can see the last searchInPlaylist(max) was called with the same argument as before i've typed in the FilterlistFragment SearchView. Why this search parameter was transferred between the two different SearchViews? And how can i reset it to default empty-string?
Is there some special handling needed in onDestroyView from the FilterlistFragment to cancel the current SearchView?
P.S.
i found the reasons but without a solution:
com.android.internal.widget.ActionBarView.ExpandedActionViewMenuPresenter#collapseItemActionView
calls
// Do this before detaching the actionview from the hierarchy, in case
// it needs to dismiss the soft keyboard, etc.
if (mExpandedActionView instanceof CollapsibleActionView) {
((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
}
this will trigger a setQuery("") and therefore a sql-search because of my setOnQueryTextListener. In the above log this was the
07-25 05:09:29.477 3315-3364/de.NullZero.ManiDroid D/DEBUG﹕searchInFilter(, ManitobaFilter{filterName='Zuletzt gehört'})
call.
On the new fragment the method
com.android.internal.view.menu.MenuBuilder#restoreActionViewStates
was called after onPrepareOptionsMenu to restore an old view state. And therefore my ActionBar/SearchView/TextView restored a (wrong) state from this Bundle with the query=max. This triggers onTextChange from SearchView and therefore an sql-search for "max" in my new-fragment as you can see as the last log-line.
how can i disable the save and restore of the ActionBar/SearchView/TextView?
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(LOGTAG, String.format("onDestroyView(%s)", this));
searchView.setOnQueryTextListener(null);
searchView.setQuery("", true);
}
This will do the trick. It's really ugly that it's impossible to use more then one SearchView because of all of them have the same TextView and therefore save/restore from the same Bundle-Key.