This is how I navigate through my app:
- Open fragment with list
- Filter list by a text entered in searchview
- Tap on listitem (list fragment gets replaced by detail fragment)
- Navigate back (detail fragment gets replaced by list fragment)
When I navigate from list- to detail-fragment, I want to keep the current filter of the searchview in a string variable. I store the value of the searchview when onQueryTextChange is executed.
The problem: I can't store the actual filter-value because onQueryTextChange gets called when I navigate from list to detail because something cleared the text of the searchview.
// ...
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
searchReceived(s);
return true;
}
});
// ...
public void searchReceived(String searchQuery)
{
this.stateHolder.searchQuery = searchQuery;
// more code...
}
When I want to restore the filter when navigating back, it just filters with an empty string because the wrong value got stored in this.stateHolder.searchQuery
.
Stack:
onQueryTextChange():139, EmployeeListFragment$1 {com.example.exampleapp.fragment}
onTextChanged():1153, SearchView {android.widget}
access$2000():92, SearchView {android.widget}
onTextChanged():1638, SearchView$11 {android.widget}
sendOnTextChanged():7408, TextView {android.widget}
setText():3816, TextView {android.widget}
setText():3671, TextView {android.widget}
setText():80, EditText {android.widget}
setText():3646, TextView {android.widget}
setQuery():511, SearchView {android.widget}
onActionViewCollapsed():1250, SearchView {android.widget}
collapseItemActionView():1662, ActionBarView$ExpandedActionViewMenuPresenter {com.android.internal.widget}
collapseItemActionView():1258, MenuBuilder {com.android.internal.view.menu}
clear():521, MenuBuilder {com.android.internal.view.menu}
doInvalidatePanelMenu():789, PhoneWindow {com.android.internal.policy.impl}
run():221, PhoneWindow$1 {com.android.internal.policy.impl}
How can I prevent the searchview from being cleared by the system when navigating?
Thanks.
I see you didn't find a solution yet, I have same problem posted here:
I found that when
invalidateOptionsMenu
is called also the methodonQueryTextChange
is called because the View launchdispatchRestoreInstanceState
with the previous value after you've cleared the search for example. Do you callinvalidateOptionsMenu
maybe?Maybe, inside
onQueryTextChange
, you can check a boolean on some current state of your application objects to know if the method content should be executed. In my case I usemDrawerLayout.isDrawerOpen(..)
to allow the search.Also you can implement the
SearchView.OnQueryTextListener
on each Class you use, on aFragment
or on the Main Activity class, somewhere in the class you could set a boolean module variable that you will check insideonQueryTextChange.
The problem is ActionBar (and subcomponents) are collapsed when the fragment holding it is replaced. When this happens the SearchView query is cleared as seen in onActionViewCollapsed. Workarounds include:
Prevent collapsing
Remove
setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
from the searchview's creation code orandroid:showAsAction="collapseActionView"
from its xml code.This will affect how/when the view's close/voicesearch buttons are displayed upon attempting to collapse it
It would also be possible to prevent collapsing by overriding SearchView's onActionViewCollapsed() method to do nothing but would accomplish the same.
Ignore query changes when appropriate
When the fragment is not valid (being replaced) then ignore query changes that would otherwise cause the fragment to alter its saved query text or layout (changing the layout would cause an exception if the fragment doesn't actually have view content).
This would be the better option as it doesn't affect the functionality of the searchview.
I modified the menu item attribute
showAsAction
fromandroid:showAsAction="always|collapseActionView"
toandroid:showAsAction="always"
. Now the look and behavior of the searchview has changed a bit, but the searchQuery doesn't get cleared!After 2 days of Googling i got the solution that will definitely helps you.
I have just
cut and pasted
code fromonCreateOptionMenu()
toonPrepareOptionMenu()
I do not know why it happens, I think listener of
searchView
is not going to beNULL
by the way you can change your code this way.and Remove:
Thanks :)
This is my solution: