Reputation: 36028
I am using the Search interface in andriod, and folowing the android guide I have set up the the interface.
I create a SearchableActivity which will handle both the user input the search result.
Now I meet a problem in that when user input something in the SearchView
and hit the search key, the Search requset will be submited, then I will receive the query string and do the search, but at this moment, the text in the SearchView
was changed to the default SearchHit
value while I want it to be the query string.
So I tried to use the searchView.setQuery(query, false);
, but it does not work, what's the problem?
The core Activity codes:
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
}
}
The 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>
Upvotes: 23
Views: 13161
Reputation: 76639
Meanwhile this works slightly different. One does not need any Runnable
or 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);
}
}
}
...
}
One has to use one search-term previously extracted from the intent and stored.
@Nullable
private String getSearchTerm() {
if (this.getMainActivity().getCurrentFragment() instanceof SomeFragment fragment) {
return fragment.getSearchTerm();
}
return null;
}
Because else one might try to access a Menu
, which had not been inflated yet.
Upvotes: 0
Reputation: 993
In my case, it wasn't working because the fragment I was in was no longer attached to the window. Moving it to above where I swapped in the new search results fragment fixed it.
Upvotes: 1
Reputation: 3420
I suggest you to delay the setting until the next event loop (add it to the message queue), so the code may looks like this:
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);
}
};
}
}
Upvotes: 19
Reputation: 2935
need to put code in post handler with 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();
Upvotes: 4
Reputation: 870
This doesn't work
mSearchView.setQuery(mKeyword, true);
MenuItemCompat.expandActionView(mMenuSearch);
This does
MenuItemCompat.expandActionView(mMenuSearch);
mSearchView.setQuery(mKeyword, true);
It seems it only remembers it after you expanded the action view. I'm using MenuItemCompat just for backwards compatibility
Upvotes: 14
Reputation: 36028
It seems that when the intent with Action Intent.ACTION_SEARCH
is received, the following method will be called:
handleIntent();
onCreateOptionsMenu();
And the handleIntent
will run before the onCreateOptionsMenu
.
At the same time, people used to setup the searchView
at the onCreateOptionsMenu
.
Which means that the option menu will be re-inflated, and the searchView
will be re-build, then all the settings in the handleIntent
will not work.
I think this is the reason.
Please feel free to fix me if I am wrong.
Upvotes: 2