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

dsc*_*ten 18 android searchview

我有一个可折叠SearchViewActionBar.执行搜索后,将关联关联ListView以仅显示匹配项.在该状态期间,SearchView仍然会展开并显示搜索字符串.如果用户关闭SearchView,我删除过滤器.

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

我恢复查询字符串onRestoreInstanceState(),如果我在onCreateOptionsMenu()调用中找到查询字符串

searchView.setQuery(query, true); 
Run Code Online (Sandbox Code Playgroud)

以便再次执行查询.事实证明,这比立即应用查询过滤器更好onRestoreInstanceState().对于后者,列表很快显示为未过滤,然后再次应用查询.有了setQuery()这不会发生.

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

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

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

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

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

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

dsc*_*ten 14

我找到了一个解决方法.这非常难看,但它确实有效.

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

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

currentQuery = state.getString(KEY_SAVED_FILTER_CONSTRAINT);
Run Code Online (Sandbox Code Playgroud)

在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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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;
} 
Run Code Online (Sandbox Code Playgroud)

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

    AutoCompleteTextView queryTextView = findQueryTextView(searchView);
    if (queryTextView != null) {
        queryTextView.dismissDropDown();
    }
Run Code Online (Sandbox Code Playgroud)

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

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

  • 不,使用支持lib,您应该使用MenuItemCompat.expandActionView(). (3认同)

Cab*_*zas 7

在我的愚见.当你想恢复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);
}
Run Code Online (Sandbox Code Playgroud)

在活动可能被杀死之前调用此方法,以便在将来某个时间返回时可以恢复其状态.现在,当用户更改方向时,可以通过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);
}
Run Code Online (Sandbox Code Playgroud)

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