有没有更好的方法来恢复SearchView状态?

我的ActionBar有一个可折叠的SearchView 。 执行搜索后,将过滤关联的ListView以仅显示匹配的项目。 在此状态期间, SearchView仍会展开并显示搜索字符串。 如果用户关闭了SearchView ,我会删除filter。

我想恢复搜索状态,例如,在配置更改时,或者当我从另一个活动返回活动时,活动是否被销毁。

我在onRestoreInstanceState()恢复查询字符串,如果我在onCreateOptionsMenu()find一个查询字符串,我调用

 searchView.setQuery(query, true); 

以便再次执行查询。 事实certificate,这比立即在onRestoreInstanceState()应用查询filter更好。 对于后者,列表很快显示为未过滤,然后再次应用查询。 使用setQuery()这不会发生。

问题:执行查询并过滤列表,但搜索视图仍保持折叠状态。 因此,用户无法使用搜索视图删除filter或应用其他查询。

onCreateOptionsMenu()我可以确定搜索项和搜索视图存在,因此我可以调用searchItem.expandActionView() 。 奇怪的是,只有这样才能真正扩展ActionView – 调用setIconified(false)不会扩展视图,即使连续两次调用它也不会。

如果我在调用setQuery() expandActionView()之前使用expandActionView() ,则会打开SearchView并显示文本(否则expandActionView()清空SearchView )。

不幸的是, expandActionView()有副作用:还会显示建议列表并打开键盘。

我可以使用searchView.clearFocus()隐藏键盘。 所以剩下的问题是建议清单。 如何在具有文本的SearchView上关闭打开的建议列表?

我想知道是否有更好的方法来恢复没有那么多副作用的动作栏中的搜索视图。

我find了一个解决方法。 它非常难看,但它确实有效。

所以这是我在配置更改后能够恢复搜索框实例状态的方法。

首先,恢复onRestoreInstanceState中的查询字符串

 currentQuery = state.getString(KEY_SAVED_FILTER_CONSTRAINT); 

在onCreateOptionsMenu中设置搜索视图,如果有currentQuery,请展开搜索项并再次提交查询。 清除焦点以隐藏键盘。

  MenuItem searchItem = menu.findItem(R.id.action_search); searchView = (SearchView) searchItem.getActionView(); searchView.setSearchableInfo(searchManager .getSearchableInfo(getComponentName())); if (!TextUtils.isEmpty(currentQuery)) { searchItem.expandActionView(); searchView.setQuery(currentQuery, true); searchView.clearFocus(); } 

最后,我们需要关闭建议清单。 以下是如何从搜索视图中获取查询文本视图:

 private AutoCompleteTextView findQueryTextView(ViewGroup viewGroup) { AutoCompleteTextView queryTextView = null; if (viewGroup != null) { int childCount = viewGroup.getChildCount(); for (int i = 0; i < childCount; i++) { View child = viewGroup.getChildAt(i); if (child instanceof AutoCompleteTextView) { queryTextView = (AutoCompleteTextView) child; break; } else if (child instanceof ViewGroup) { queryTextView = findQueryTextView((ViewGroup) child); if (queryTextView != null) { break; } } } } return queryTextView; } 

然后你可以解雇建议清单:

  AutoCompleteTextView queryTextView = findQueryTextView(searchView); if (queryTextView != null) { queryTextView.dismissDropDown(); } 

但是,这在onCreateOptionsMenu中不起作用。 我不得不将dismissDropDown的调用移动到我的活动的onNewIntent方法中以使其工作。

使这如此丑陋的原因是恢复步骤分散在生命周期的各个阶段,并且需要递归视图搜索才能到达建议列表。

在我的愚见。 当你想恢复searchView状态时,我们应该使用onSaveInstanceState(Bundle outState) 。 被调用以在被杀死之前从活动中检索每个实例状态,以便可以在onCreate(Bundle)或onRestoreInstanceState(Bundle)中恢复状态(由此方法填充的Bundle将被传递给两者)。

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // if you saved something on outState you can recover them here if (savedInstanceState != null) { mSearchString = savedInstanceState.getString(SEARCH_KEY); } } // This is called before the activity is destroyed @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mSearchString = mSearchView.getQuery().toString(); outState.putString(SEARCH_KEY, mSearchString); } 

在活动可能被杀死之前调用此方法,以便在将来某个时间返回时它可以恢复其状态。 现在,当用户更改方向时,可以通过onCreate(Bundle)或onRestoreInstanceState(Bundle)恢复用户界面的状态。

现在我们应该使用onCreateOptionsMenu(菜单菜单) ,因为我们需要关注我们的SearchView。

 @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); MenuItem searchMenuItem = menu.findItem(R.id.menu_main_action_search); mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem); //focus the SearchView if (mSearchString != null && !mSearchString.isEmpty()) { searchMenuItem.expandActionView(); mSearchView.setQuery(mSearchString, true); mSearchView.clearFocus(); } return super.onCreateOptionsMenu(menu); } 

您也可以使用完整代码查看此链接 。