有没有更好的方法来恢复SearchView状态?
我的ActionBar
有一个可折叠的SearchView
。 执行搜索后,关联的ListView
被过滤以仅显示匹配的项目。 在该状态期间, SearchView
仍然展开并显示搜索字符串。 如果用户关闭SearchView
,我将删除筛选器。
我想恢复搜索状态,例如在配置更改时,或者当我从其他活动返回时,活动已被销毁。
我在onRestoreInstanceState()
恢复查询字符串,如果我在onCreateOptionsMenu()
找到查询字符串,
searchView.setQuery(query, true);
以便再次执行查询。 事实证明,这比在onRestoreInstanceState()
立即应用查询过滤器onRestoreInstanceState()
。 对于后者,该列表将很快显示为未过滤,只有当查询再次应用时才会显示。 使用setQuery()
这不会发生。
问题:查询被执行并且列表被过滤,但搜索视图保持折叠状态。 因此,用户不能使用搜索视图来删除过滤器或应用其他查询。
在onCreateOptionsMenu()
我可以确定搜索项和搜索视图存在,因此我可以调用searchItem.expandActionView()
。 奇怪的是,只有这样才能真正扩展ActionView
- 调用setIconified(false)
不会扩展视图,即使它连续调用两次。
如果在调用setQuery()
expandActionView()
之前使用expandActionView()
,将打开SearchView
并显示文本(否则expandActionView()
将清空SearchView
)。
不幸的是, expandActionView()
有一个副作用:显示建议列表并打开键盘。
我可以使用searchView.clearFocus()
隐藏键盘。 所以剩下的问题就是建议列表。 如何关闭包含文本的SearchView
上的打开建议列表?
我想知道是否有更好的方法来恢复没有太多副作用的操作栏中的搜索视图。
我找到了一个解决方法。 这是非常丑陋的,但它的作品。
所以这里是我如何在配置更改后恢复搜索框实例状态。
首先,恢复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);
}
你也可以用完整的代码检查这个链接。
链接地址: http://www.djcxy.com/p/92959.html上一篇: Is there a better way to restore SearchView state?
下一篇: Hide the keyboard after a user finishes a query on a SearchView