Android: Return search query to current activity
我按照http://developer.android.com/guide/topics/search/search-dialog.html中描述的步骤在我的记事本应用程序中实现搜索功能。
我的问题是,当我完成搜索时,一个新的活动将打开,捕获我的搜索查询。但我真正想要的是返回到当前活动的查询,而不是启动新的查询。
这有可能吗?
更新:
androidmanifest.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 | <wyn> <activity android:name="MyNotepad" android:label="@string/app_name"> <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </action> </intent-filter> <meta-data android:resource="@xml/searchable" android:name="android.app.searchable"></meta-data> </activity> </activity> </wyn> |
搜索XML
1 2 3 4 5 6 7 8 | <wyn> <?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint"> </searchable> </wyn> |
Java代码
1 2 3 4 5 6 7 8 9 10 11 12 | <wyn> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_pad); Intent intent = getIntent(); if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); Toast.makeText(getApplicationContext(), query, Toast.LENGTH_LONG).show(); } } </wyn> |
1 2 3 4 5 6 7 8 9 10 11 12 13 | <wyn> @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case R.id.menuItemSearch: startSearch("", false, null, false); break; } return true; } </wyn> |
即使我用手机上的搜索按钮也不行。因此,我认为问题出在androidmanifest.xml中。
在应用程序清单中,需要将当前活动定义为可搜索的活动。
1 2 3 4 5 6 7 8 | <activity android:name="BrowseItems" android:label="@string/browseitems" android:launchMode="singleTop"> <intent-filter> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/itemsearchable" /> </activity> |
然后使用以下代码,该代码来自http://developer.android.com/guide/topics/search/search dialog.html lifecycle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.search); handleIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { setIntent(intent); handleIntent(intent); } private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); // Do work using string } } |
然后可以使用字符串重新加载活动,如果它是列表活动,则可以调用用于加载数据的代码,并在其中使用字符串。
在可搜索活动中添加到androidmanifest.xml:
1 | android:launchMode="singleTop" |
因此,您的androidmanifest.xml看起来如下:
1 2 3 4 5 6 7 8 9 10 | <activity android:name="MyNotepad" android:label="@string/app_name" android:launchMode="singleTop"> <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </action> </intent-filter> <meta-data android:resource="@xml/searchable" android:name="android.app.searchable"></meta-data> </activity> |
原因:
从这个帖子:
活动启动模式有四个有效值:
"标准""独角戏""单选""单实例"
"标准"是默认值。这四个值分为两组:
"standard"和"singletop"可以实例化多个活动实例,实例将保留在同一任务中。对于"singletask"或"singleinstance",activity类使用singleton模式,该实例将成为新任务的根Activity。让我们检查每个值:"标准":
可以实例化活动类的多个实例,并且可以将多个实例添加到同一个任务或不同的任务中。这是大多数活动的通用模式。
"独角戏":
与"标准"的区别在于,如果当前任务的顶部已经存在活动的实例,并且系统将意向路由到此活动,则不会创建新实例,因为它将触发onNewIntent()方法而不是创建新对象。
我只是用这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 | searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { //on submit return false; } @Override public boolean onQueryTextChange(String s) { //get all text changes return false; } }); |
当必须在ListView中搜索并筛选出项时,最好使用此选项。我从不使用清单文件实现搜索函数。这两种方法完成了所有的工作。
我也面临同样的问题,然后我写了这个代码,它解决了我的问题。
在您的活动中实现这一点
1 | **implements SearchView.OnQueryTextListener, SearchView.OnCloseListener** |
在类中添加此函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | private void setupSearchView() { searchView.setIconifiedByDefault(true); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); if (searchManager != null) { List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch(); // Try to use the"applications" global search provider SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); for (SearchableInfo inf : searchables) { if (inf.getSuggestAuthority() != null && inf.getSuggestAuthority().startsWith("applications")) { info = inf; } } searchView.setSearchableInfo(info); } searchView.setOnQueryTextListener(this); searchView.setOnCloseListener(this); } |
调用onCreateOptions菜单(菜单菜单)中的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); //restoreActionBar(); // Associate searchable configuration with the SearchView //SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); searchView = (SearchView) menu.findItem(R.id.action_search).getActionView(); //searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); setupSearchView(); return super.onCreateOptionsMenu(menu); } |
这完全可以解决你的问题。
快乐编码!!
简要地:
在清单文件中,添加:
1 | android:launchMode="singleTop" |
搜索活动。然后,让搜索活动实现searchview.onsuggestionListener最后:
1 | mSearchView.setOnSuggestListener(this) |
通过这种方式,您可以在不创建搜索活动的新实例的情况下处理建议单击事件。
我按照拉克兰的提示"你可以用这个字符串重新加载你的活动",最后解决了这个问题。因此,请先阅读Lachlan的帖子,然后采取以下3个步骤"重新加载您的活动":
列表活动中的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String searchText = intent.getStringExtra(SearchManager.QUERY); ((MyApp)this.getApplicationContext()).setSearchText(searchText); this.finish(); } } protected void onResume() { super.onResume(); String searchText = ((MyApp)this.getApplicationContext()).getSearchText(); //refresh your list here... } |
myapp类:(这个最初的想法来自这里:android:如何声明全局变量?)
1 2 3 4 5 6 7 8 9 10 11 12 | public class MyApp extends Application { private String mSearchText; public String getSearchText() { return mSearchText; } public void setSearchText(String searchText) { this.mSearchText = searchText; } } |
不要忘记将属性
如果SearchView上的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { @Override public boolean onSuggestionSelect(int position) { return true; } @Override public boolean onSuggestionClick(int position) { CursorAdapter selectedView = searchView.getSuggestionsAdapter(); Cursor cursor = (Cursor) selectedView.getItem(position); int index = cursor.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1); searchView.setQuery(cursor.getString(index), true); return true; } }); |
无需强制将活动设置为单顶或其他黑客。
只要添加
1 2 3 4 5 6 7 | <meta-data android:name="android.app.default_searchable" android:value="#Activity_Name" /> <!-- All your activities, service, etc. --> </application> |
在android的manifest.xml文件中,activity name是处理搜索的活动的名称。