我正在andriod中使用搜索界面,并按照android指南设置了界面。
我创建一个 SearchableActivity 它将处理用户输入和搜索结果。
现在我遇到一个问题,当用户在
SearchView
中输入内容并点击搜索键时,搜索请求将被提交,然后我将收到查询字符串并进行搜索,但此时,中的文本SearchView
已更改为默认 SearchHit
值,而我希望它是查询字符串。
所以我尝试使用
searchView.setQuery(query, false);
,但它不起作用,有什么问题吗?
核心Activity代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_activity_layout);
Log.d("map", "create");
handleIntent(getIntent());
}
public void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
Log.d("map", "handleIntent");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//try search
Log.d("map", "search and set query:" + query);
searchView.setQuery(query, false); // reset the value in of the SearchView
}
}
AndroidManifest.xml:
<activity
android:name=".ui.MapActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
我建议你延迟设置,直到下一个事件循环(将其添加到消息队列),所以代码可能如下所示:
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
final String query = intent.getStringExtra(SearchManager.QUERY);
searchView.post(new Runnable() {
@Override
public void run() {
// Important! Make sure searchView has been initialized
// and referenced to the correct (current) SearchView.
// Config changes (e.g. screen rotation) may make the
// variable value null.
searchView.setQuery(query, false);
}
};
}
}
这行不通
mSearchView.setQuery(mKeyword, true);
MenuItemCompat.expandActionView(mMenuSearch);
这样
MenuItemCompat.expandActionView(mMenuSearch);
mSearchView.setQuery(mKeyword, true);
似乎只有在您展开操作视图后它才会记住它。 我使用 MenuItemCompat 只是为了向后兼容
需要将代码放入带有 MenuItemCompat 的后处理程序中
inflater.inflate(R.menu.menu_my_team, menu);
// search manager integration for search widget
SearchManager searchManager = (SearchManager) getActivity()
.getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
// MenuItem helpTutorialMenuItem = menu.findItem(R.id.action_help);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
mSearchView.setSearchableInfo(searchManager
.getSearchableInfo(getActivity().getComponentName()));
mSearchView.setQueryHint("Search by");
if (!TextUtils.isEmpty(queryText)) {
mSearchView.post(new Runnable() {
@Override
public void run() {
MenuItemCompat.expandActionView(searchMenuItem);
mSearchView.setQuery(queryText, false);
}
});
}
mSearchView.clearFocus();
似乎当收到Action
Intent.ACTION_SEARCH
的intent时,会调用以下方法:
handleIntent();
onCreateOptionsMenu();
并且
handleIntent
将在 onCreateOptionsMenu
之前运行。
同时,人们习惯于将
searchView
设置在onCreateOptionsMenu
处。
这意味着选项菜单将重新膨胀,并且
searchView
将被重新构建,那么handleIntent
中的所有设置将不起作用。
我想这就是原因。
如果我错了,请随时纠正我。
就我而言,它不起作用,因为我所在的片段不再附加到窗口。将其移动到上面我交换新搜索结果片段的位置修复了它。
同时,这的工作原理略有不同。不需要任何
Runnable
或 MenuCompat
...
public class SomeMenuProvider implements MenuProvider {
/** Setting up the SearchView. */
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(this.resId, menu);
MenuItem searchItem = menu.findItem(R.id.menu_action_search_view);
this.searchView = (SearchView) searchItem.getActionView();
if (this.searchView != null) {
this.searchView.setOnQueryTextListener(this.listener);
SearchManager searchManager = (SearchManager) this.getMainActivity().getSystemService(Context.SEARCH_SERVICE);
ComponentName component = new ComponentName(this.getMainActivity(), MainActivity.class);
SearchableInfo searchableInfo = searchManager.getSearchableInfo(component);
this.searchView.setSearchableInfo(searchableInfo);
String searchTerm = this.getSearchTerm();
if (searchTerm != null) {
searchItem.expandActionView();
searchView.setQuery(searchTerm, false);
}
}
}
...
}
必须使用之前从意图中提取并存储的一个搜索词。
@Nullable
private String getSearchTerm() {
if (this.getMainActivity().getCurrentFragment() instanceof SomeFragment fragment) {
return fragment.getSearchTerm();
}
return null;
}
因为否则人们可能会尝试访问尚未膨胀的
Menu
。