Opening/Closing NavDrawer with invalidateOptionsMenu() cause onRestore call on SearchView and onQueryTextChange is called as well

雨燕双飞 提交于 2019-12-04 04:25:16

问题


I have a MainActivity with callbacks implementation of:

  • DrawerListFragment.Callback
  • ItemListFragment.Callbacks
  • SearchView.OnQueryTextListener

I have also added an ActionBar SearchView, and finally implemented OnQueryTextListener to change the listView of the listFragment at each kb type, but this works! Also, clicking an item on navDrawer generates a new/replace FragmentList transaction for the new type of itemsList.

Now the problem. The ActionBar SearchView actually filters the current itemList created.

Opening/closing NavDrawer is made with the classic "new ActionBarDrawerToggle(){...}" implementation with invalidateOptionsMenu() in the override methods. But this calling fires onQueryTextChange execution everytime the drawer is opened/closed... See logs! I've purposely generate an exception to see the stacktrace behind these calls: onRestore is actually called for the SearchView, my question is why and how to avoid this automatic trigger for the SearchView?

I may check inside onQueryTextChange if the drawer is opened to avoid the regeneration of the itemsList. This could be a solution, but I would like to know what you think and if another solution exists.

If not clear I may upload some codes. Logs are here:

Apps shows ALL items at start (Drawer position 0).

10-30 14:34:47.871: V/com.dav.pc.ui.MainActivity(900): MainActivity.initializeDrawer called!
10-30 14:34:47.880: D/com.dav.pc.ui.DrawerListFragment(900): New Drawer Instance!
10-30 14:34:47.900: D/com.dav.pc.ui.MainActivity(900): MainActivity.initializeActivity NewLaunch=Tutti gli elementi
10-30 14:34:47.920: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected List selected: ALL
10-30 14:34:47.920: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected Transaction Commit
10-30 14:34:47.920: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected Label selected: ALL
10-30 14:34:47.930: V/com.dav.pc.ui.DrawerListFragment(900): DrawerListFragment.onCreate() called!
10-30 14:34:47.930: D/com.dav.pc.ui.DrawerListFragment(900): SetPosition onCreate activated_position=-1
10-30 14:34:47.980: V/com.dav.pc.ui.DrawerListFragment(900): DrawerListFragment.onViewCreated() called!
10-30 14:34:47.980: D/com.dav.pc.ui.DrawerListFragment(900): activated_position=0
10-30 14:34:47.980: V/com.dav.pc.ui.DrawerListFragment(900): DrawerListFragment.setSelection() called!
10-30 14:34:47.980: D/com.dav.pc.ui.DrawerListFragment(900): CurrentPosition=0
10-30 14:34:47.980: V/com.dav.pc.ui.DrawerListFragment(900): DrawerListFragment.onActivityCreated() called!
10-30 14:34:47.990: D/com.dav.pc.ui.ItemListFragment(900): ItemListFragment.onCreate Bundle exists
10-30 14:34:47.990: D/com.dav.pc.ui.ItemListFragment(900): Bundle[{list_id=ALL}]
10-30 14:34:47.990: D/com.dav.pc.ui.ItemListFragment(900): Create List ALL (16 items)
10-30 14:34:48.001: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:34:48.001: I/System.out(900): [mFirstLetters>Item 1,1]
10-30 14:34:48.001: I/System.out(900): [mFirstLetters>Item 10,2]
10-30 14:34:48.001: I/System.out(900): [mFirstLetters>Item 11,3]
10-30 14:34:48.010: I/System.out(900): [mFirstLetters>Item 12,4]
10-30 14:34:48.010: I/System.out(900): [mFirstLetters>Item 13,5]
10-30 14:34:48.010: I/System.out(900): [mFirstLetters>Item 14,6]
10-30 14:34:48.020: I/System.out(900): [mFirstLetters>Item 15,7]
10-30 14:34:48.020: I/System.out(900): [mFirstLetters>Item 2,8]
10-30 14:34:48.020: I/System.out(900): [mFirstLetters>Item 3,9]
10-30 14:34:48.030: I/System.out(900): [mFirstLetters>Item 4,10]
10-30 14:34:48.040: I/System.out(900): [mFirstLetters>Item 5,11]
10-30 14:34:48.040: I/System.out(900): [mFirstLetters>Item 6,12]
10-30 14:34:48.051: I/System.out(900): [mFirstLetters>Item 7,13]
10-30 14:34:48.051: I/System.out(900): [mFirstLetters>Item 8,14]
10-30 14:34:48.051: I/System.out(900): [mFirstLetters>Item 9,15]
10-30 14:34:48.090: V/com.dav.pc.ui.MainActivity(900): onPostCreate called!
10-30 14:34:48.101: V/com.dav.pc.ui.ItemListFragment(900): ItemListFragment.onResume() called!
10-30 14:34:48.710: V/com.dav.pc.ui.MainActivity(900): MainActivity.onCreateOptionsMenu called!
I type 0 in the searchView:
10-30 14:34:55.421: V/com.dav.pc.ui.MainActivity(900): MainActivity.onQueryTextChange() newText: 0
10-30 14:34:55.440: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:34:55.440: I/System.out(900): [mFirstLetters>Item 10,1]
this is another strange behaviour: getItemId in the ItemListAdapter is called 5 times... always, why?
10-30 14:34:55.470: D/com.dav.pc.ui.ItemListAdapter(900): getItemId position: 0
10-30 14:34:55.470: D/com.dav.pc.ui.ItemListAdapter(900): getItemId position: 0
10-30 14:34:55.490: D/com.dav.pc.ui.ItemListAdapter(900): getItemId position: 0
10-30 14:34:55.490: D/com.dav.pc.ui.ItemListAdapter(900): getItemId position: 0
10-30 14:34:55.540: D/com.dav.pc.ui.ItemListAdapter(900): getItemId position: 0
10-30 14:35:01.940: V/com.dav.pc.ui.MainActivity(900): MainActivity.onCreateOptionsMenu called!
onQueryTextChange is fired.
Here my controlled exception, method triggered when Drawer is opened!
This method creates a new ItemListAdapter and passed to the mItemListFragment:
10-30 14:35:02.080: V/com.dav.pc.ui.MainActivity(900): MainActivity.onQueryTextChange() newText: 0
10-30 14:35:02.090: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:35:02.100: I/System.out(900): [mFirstLetters>Item 10,1]
10-30 14:35:01.980: W/System.err(900):  at com.dav.pc.ui.MainActivity.onQueryTextChange(MainActivity.java:306)
10-30 14:35:01.990: W/System.err(900):  at android.widget.SearchView.onTextChanged(SearchView.java:1081)
10-30 14:35:01.990: W/System.err(900):  at android.widget.SearchView.access$1900(SearchView.java:90)
10-30 14:35:01.990: W/System.err(900):  at android.widget.SearchView$10.onTextChanged(SearchView.java:1536)
10-30 14:35:01.990: W/System.err(900):  at android.widget.TextView.sendOnTextChanged(TextView.java:7577)
10-30 14:35:01.990: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3259)
10-30 14:35:02.000: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3110)
10-30 14:35:02.000: W/System.err(900):  at android.widget.EditText.setText(EditText.java:78)
10-30 14:35:02.000: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3085)
10-30 14:35:02.000: W/System.err(900):  at android.widget.TextView.onRestoreInstanceState(TextView.java:2985)
10-30 14:35:02.000: W/System.err(900):  at android.view.View.dispatchRestoreInstanceState(View.java:9876)
10-30 14:35:02.010: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:02.010: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:02.010: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:02.010: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:02.020: W/System.err(900):  at android.view.View.restoreHierarchyState(View.java:9854)
10-30 14:35:02.020: W/System.err(900):  at com.android.internal.view.menu.MenuBuilder.restoreActionViewStates(MenuBuilder.java:358)
10-30 14:35:02.020: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:412)
10-30 14:35:02.020: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:739)
10-30 14:35:02.030: W/System.err(900):  at android.app.Activity.invalidateOptionsMenu(Activity.java:2552)
10-30 14:35:02.030: W/System.err(900):  at com.dav.pc.ui.MainActivity$1.onDrawerOpened(MainActivity.java:187)
10-30 14:35:02.030: W/System.err(900):  at android.support.v4.widget.DrawerLayout.dispatchOnDrawerOpened(DrawerLayout.java:488)
10-30 14:35:02.040: W/System.err(900):  at android.support.v4.widget.DrawerLayout.updateDrawerState(DrawerLayout.java:459)
10-30 14:35:02.040: W/System.err(900):  at android.support.v4.widget.DrawerLayout$ViewDragCallback.onViewDragStateChanged(DrawerLayout.java:1355)
...
10-30 14:35:42.040: V/com.dav.pc.ui.MainActivity(900): MainActivity.onCreateOptionsMenu called!
This is my controlled exception, method triggered when Drawer is closed.
Again the execution of the method.
10-30 14:35:42.170: V/com.dav.pc.ui.MainActivity(900): MainActivity.onQueryTextChange() newText: 0
10-30 14:35:42.170: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:35:42.180: I/System.out(900): [mFirstLetters>Item 10,1]
10-30 14:35:42.080: W/System.err(900):  at com.dav.pc.ui.MainActivity.onQueryTextChange(MainActivity.java:306)
10-30 14:35:42.080: W/System.err(900):  at android.widget.SearchView.onTextChanged(SearchView.java:1081)
10-30 14:35:42.090: W/System.err(900):  at android.widget.SearchView.access$1900(SearchView.java:90)
10-30 14:35:42.090: W/System.err(900):  at android.widget.SearchView$10.onTextChanged(SearchView.java:1536)
10-30 14:35:42.090: W/System.err(900):  at android.widget.TextView.sendOnTextChanged(TextView.java:7577)
10-30 14:35:42.090: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3259)
10-30 14:35:42.090: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3110)
10-30 14:35:42.090: W/System.err(900):  at android.widget.EditText.setText(EditText.java:78)
10-30 14:35:42.100: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3085)
10-30 14:35:42.100: W/System.err(900):  at android.widget.TextView.onRestoreInstanceState(TextView.java:2985)
10-30 14:35:42.100: W/System.err(900):  at android.view.View.dispatchRestoreInstanceState(View.java:9876)
10-30 14:35:42.110: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:42.110: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:42.110: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:42.110: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:35:42.120: W/System.err(900):  at android.view.View.restoreHierarchyState(View.java:9854)
10-30 14:35:42.120: W/System.err(900):  at com.android.internal.view.menu.MenuBuilder.restoreActionViewStates(MenuBuilder.java:358)
10-30 14:35:42.120: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:412)
10-30 14:35:42.120: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:739)
10-30 14:35:42.130: W/System.err(900):  at android.app.Activity.invalidateOptionsMenu(Activity.java:2552)
10-30 14:35:42.130: W/System.err(900):  at com.dav.pc.ui.MainActivity$1.onDrawerClosed(MainActivity.java:180)
10-30 14:35:42.140: W/System.err(900):  at android.support.v4.widget.DrawerLayout.dispatchOnDrawerClosed(DrawerLayout.java:477)
10-30 14:35:42.140: W/System.err(900):  at android.support.v4.widget.DrawerLayout.updateDrawerState(DrawerLayout.java:457)
10-30 14:35:42.140: W/System.err(900):  at android.support.v4.widget.DrawerLayout$ViewDragCallback.onViewDragStateChanged(DrawerLayout.java:1355)
....

=========================================================================
This is when instead I select a new ItemDrawer to generate the new list with fragment transaction:
10-30 14:37:47.961: D/com.dav.pc.ui.DrawerListAdapter(900): getItemId position: 5
10-30 14:37:48.100: D/com.dav.pc.ui.DrawerListAdapter(900): getItemId position: 5
10-30 14:37:48.100: D/com.dav.pc.ui.DrawerListAdapter(900): getItemId position: 0
10-30 14:37:48.100: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected ListId selected: 4
10-30 14:37:48.100: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected ClearSearch
10-30 14:37:48.161: V/com.dav.pc.ui.MainActivity(900): MainActivity.onQueryTextChange() newText: 
(I Should avoid this useless generation when clearing the searchText)
10-30 14:37:48.170: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:37:48.170: I/System.out(900): [mFirstLetters>Item 1,1]
10-30 14:37:48.170: I/System.out(900): [mFirstLetters>Item 10,2]
10-30 14:37:48.170: I/System.out(900): [mFirstLetters>Item 11,3]
10-30 14:37:48.170: I/System.out(900): [mFirstLetters>Item 12,4]
10-30 14:37:48.181: I/System.out(900): [mFirstLetters>Item 13,5]
10-30 14:37:48.181: I/System.out(900): [mFirstLetters>Item 14,6]
10-30 14:37:48.181: I/System.out(900): [mFirstLetters>Item 15,7]
10-30 14:37:48.181: I/System.out(900): [mFirstLetters>Item 2,8]
10-30 14:37:48.181: I/System.out(900): [mFirstLetters>Item 3,9]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 4,10]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 5,11]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 6,12]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 7,13]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 8,14]
10-30 14:37:48.191: I/System.out(900): [mFirstLetters>Item 9,15]
Again my controlled exception to see the stacktrace:
10-30 14:37:48.111: W/System.err(900):  at com.dav.pc.ui.MainActivity.onQueryTextChange(MainActivity.java:306)
10-30 14:37:48.111: W/System.err(900):  at android.widget.SearchView.onTextChanged(SearchView.java:1081)
10-30 14:37:48.111: W/System.err(900):  at android.widget.SearchView.access$1900(SearchView.java:90)
10-30 14:37:48.121: W/System.err(900):  at android.widget.SearchView$10.onTextChanged(SearchView.java:1536)
10-30 14:37:48.121: W/System.err(900):  at android.widget.TextView.sendOnTextChanged(TextView.java:7577)
10-30 14:37:48.121: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3259)
10-30 14:37:48.121: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3110)
10-30 14:37:48.121: W/System.err(900):  at android.widget.EditText.setText(EditText.java:78)
10-30 14:37:48.121: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3085)
10-30 14:37:48.131: W/System.err(900):  at android.widget.SearchView.setQuery(SearchView.java:481)
10-30 14:37:48.131: W/System.err(900):  at com.dav.pc.ui.MainActivity.onDrawerItemSelected(MainActivity.java:210)
10-30 14:37:48.131: W/System.err(900):  at com.dav.pc.ui.DrawerListFragment.onListItemClick(DrawerListFragment.java:153)
10-30 14:37:48.131: W/System.err(900):  at android.app.ListFragment$2.onItemClick(ListFragment.java:160)
...
10-30 14:37:48.201: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected Transaction Commit
10-30 14:37:48.201: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected Label selected: 4
10-30 14:37:48.201: D/com.dav.pc.ui.MainActivity(900): MainActivity.onDrawerItemSelected ClosingDrawer
10-30 14:37:48.201: V/com.dav.pc.ui.DrawerListFragment(900): DrawerListFragment.setSelection() called!
10-30 14:37:48.211: D/com.dav.pc.ui.DrawerListFragment(900): CurrentPosition=5
10-30 14:37:48.211: D/com.dav.pc.ui.DrawerListAdapter(900): getItemId position: 0
10-30 14:37:48.211: D/com.dav.pc.ui.DrawerListAdapter(900): getItemId position: 5
10-30 14:37:48.411: V/com.dav.pc.ui.ItemListFragment(900): ItemListFragment.onPause() called!
10-30 14:37:48.431: D/com.dav.pc.ui.ItemListFragment(900): ItemListFragment.onCreate Bundle exists
10-30 14:37:48.431: D/com.dav.pc.ui.ItemListFragment(900): Bundle[{list_id=4}]
10-30 14:37:48.431: D/com.dav.pc.ui.ItemListFragment(900): Create List 4
(The list 4 contains 6 items, we are in onCreate)
10-30 14:37:48.431: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:37:48.431: I/System.out(900): [mFirstLetters>Item 1,1]
10-30 14:37:48.431: I/System.out(900): [mFirstLetters>Item 2,2]
10-30 14:37:48.441: I/System.out(900): [mFirstLetters>Item 3,3]
10-30 14:37:48.441: I/System.out(900): [mFirstLetters>Item 4,4]
10-30 14:37:48.441: I/System.out(900): [mFirstLetters>Item 5,5]
10-30 14:37:48.461: V/com.dav.pc.ui.ItemListFragment(900): ItemListFragment.onResume() called!
10-30 14:37:48.721: V/com.dav.pc.ui.MainActivity(900): MainActivity.onCreateOptionsMenu called!
10-30 14:37:48.811: V/com.dav.pc.ui.MainActivity(900): MainActivity.onQueryTextChange() newText: 
10-30 14:37:48.811: I/System.out(900): [mFirstLetters>Item 0,0]
10-30 14:37:48.811: I/System.out(900): [mFirstLetters>Item 1,1]
10-30 14:37:48.821: I/System.out(900): [mFirstLetters>Item 2,2]
10-30 14:37:48.821: I/System.out(900): [mFirstLetters>Item 3,3]
10-30 14:37:48.821: I/System.out(900): [mFirstLetters>Item 4,4]
10-30 14:37:48.821: I/System.out(900): [mFirstLetters>Item 5,5]
10-30 14:37:48.761: W/System.err(900):  at com.dav.pc.ui.MainActivity.onQueryTextChange(MainActivity.java:306)
10-30 14:37:48.761: W/System.err(900):  at android.widget.SearchView.onTextChanged(SearchView.java:1081)
10-30 14:37:48.761: W/System.err(900):  at android.widget.SearchView.access$1900(SearchView.java:90)
10-30 14:37:48.761: W/System.err(900):  at android.widget.SearchView$10.onTextChanged(SearchView.java:1536)
10-30 14:37:48.761: W/System.err(900):  at android.widget.TextView.sendOnTextChanged(TextView.java:7577)
10-30 14:37:48.761: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3259)
10-30 14:37:48.761: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3110)
10-30 14:37:48.771: W/System.err(900):  at android.widget.EditText.setText(EditText.java:78)
10-30 14:37:48.771: W/System.err(900):  at android.widget.TextView.setText(TextView.java:3085)
10-30 14:37:48.771: W/System.err(900):  at android.widget.TextView.onRestoreInstanceState(TextView.java:2985)
10-30 14:37:48.771: W/System.err(900):  at android.view.View.dispatchRestoreInstanceState(View.java:9876)
10-30 14:37:48.771: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:37:48.771: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:37:48.781: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:37:48.781: W/System.err(900):  at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330)
10-30 14:37:48.781: W/System.err(900):  at android.view.View.restoreHierarchyState(View.java:9854)
10-30 14:37:48.781: W/System.err(900):  at com.android.internal.view.menu.MenuBuilder.restoreActionViewStates(MenuBuilder.java:358)
10-30 14:37:48.781: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:412)
10-30 14:37:48.781: W/System.err(900):  at com.android.internal.policy.impl.PhoneWindow.invalidatePanelMenu(PhoneWindow.java:739)
10-30 14:37:48.791: W/System.err(900):  at android.app.Activity.invalidateOptionsMenu(Activity.java:2552)
10-30 14:37:48.791: W/System.err(900):  at com.dav.pc.ui.MainActivity$1.onDrawerClosed(MainActivity.java:180)
...

回答1:


I just found a new solution that worked for me very clean, maybe someone else is interested:

In the open/close implementation of the Drawer I call directly onPrepareOptionsMenu(mMenu) instead of invalidateOptionsMenu().

As you see, I use the instance of the menu saved in mMenu at its creation. Calling this method I avoid to invalidate the searchView, that still could contain some text, therefore not to be cleared.

Here another trick (always inside onPrepareOptionsMenu) to clear/iconify the searchView I check if currently a searchText is previously set in my Service class:

if (!Service.getInstance().hasSearchText()) {
    Log.d(MainActivity.class.getSimpleName(), "onPrepareOptionsMenu Clearing SearchView!");
    SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
    searchView.setIconified(true);// This also clears the text in SearchView widget
}


来源:https://stackoverflow.com/questions/26655992/opening-closing-navdrawer-with-invalidateoptionsmenu-cause-onrestore-call-on-s

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!