I've add search view widget to my action bar and would like to handle autocomplete feature. After writing more then 3 letters it should fulfill http request to my web API which will return json result and should show search widget suggestions. But in documentation is observed the case with content providers. How can I organize autocomplete feature?
我已经将search view小部件添加到我的操作栏中,并希望处理自动完成功能。在写了超过3个字母后,它应该完成对我的web API的http请求,该API将返回json结果并显示搜索小部件建议。但是在文档中可以观察到内容提供者的情况。如何组织自动完成功能?
Added search view in menu xml file:
在菜单xml文件中添加搜索视图:
<item android:id="@+id/search"
android:icon="@drawable/ic_search_white_24dp"
android:title="Search"
[namespace]:showAsAction="always"
[namespace]:actionViewClass="android.widget.SearchView" />
Associates searchable configuration with the SearchView:
关联可搜索配置与SearchView:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.navigation, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
Added searchable configuration:
添加搜索配置:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint"
android:searchSuggestAuthority="com.my.domain.searchable_activity" />
And ultimately added empty responsible activity.
最终增加了空的负责任的活动。
1 个解决方案
#1
15
You can't do this with setSearchableInfo()
and a search configuration.
对于setSearchableInfo()和搜索配置,您不能这样做。
The problem is that SearchView
needs a CursorAdapter
and you are retrieving data from the server, not the database.
问题是SearchView需要一个CursorAdapter,您正在从服务器检索数据,而不是数据库。
However, I have done something like this before with these steps:
然而,我以前就做过这样的事情:
-
Set up your
SearchView
to use aCursorAdapter
;设置SearchView以使用CursorAdapter;
searchView.setSuggestionsAdapter(new SimpleCursorAdapter( context, android.R.layout.simple_list_item_1, null, new String[] { SearchManager.SUGGEST_COLUMN_TEXT_1 }, new int[] { android.R.id.text1 }));
-
Create an
AsyncTask
to read the JSON data from your server and create aMatrixCursor
from the data:创建一个AsyncTask从服务器读取JSON数据,并从数据中创建一个MatrixCursor:
public class FetchSearchTermSuggestionsTask extends AsyncTask<String, Void, Cursor> { private static final String[] sAutocompleteColNames = new String[] { BaseColumns._ID, // necessary for adapter SearchManager.SUGGEST_COLUMN_TEXT_1 // the full search term }; @Override protected Cursor doInBackground(String... params) { MatrixCursor cursor = new MatrixCursor(sAutocompleteColNames); // get your search terms from the server here, ex: JSONArray terms = remoteService.getTerms(params[0]); // parse your search terms into the MatrixCursor for (int index = 0; index < terms.length(); index++) { String term = terms.getString(index); Object[] row = new Object[] { index, term }; cursor.addRow(row); } return cursor; } @Override protected void onPostExecute(Cursor result) { searchView.getSuggestionsAdapter().changeCursor(result); } }
-
Set an
OnQueryTextListener
to kick off your remote server task or start your search activity:设置一个OnQueryTextListener以启动远程服务器任务或启动搜索活动:
searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextChange(String query) { if (query.length() >= SEARCH_QUERY_THRESHOLD) { new FetchSearchTermSuggestionsTask().execute(query); } else { searchView.getSuggestionsAdapter().changeCursor(null); } return true; } @Override public boolean onQueryTextSubmit(String query) { // if user presses enter, do default search, ex: if (query.length() >= SEARCH_QUERY_THRESHOLD) { Intent intent = new Intent(MainActivity.this, SearchableActivity.class); intent.setAction(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, query); startActivity(intent); searchView.getSuggestionsAdapter().changeCursor(null); return true; } } });
-
Set an
OnSuggestionListener
on theSearchView
to execute your search:在SearchView上设置一个on合理化监听器来执行您的搜索:
searchView.setOnSuggestionListener(new OnSuggestionListener() { @Override public boolean onSuggestionSelect(int position) { Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem(position); String term = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1)); cursor.close(); Intent intent = new Intent(MainActivity.this, SearchableActivity.class); intent.setAction(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, term); startActivity(intent); return true; } @Override public boolean onSuggestionClick(int position) { return onSuggestionSelect(position); } });
#1
15
You can't do this with setSearchableInfo()
and a search configuration.
对于setSearchableInfo()和搜索配置,您不能这样做。
The problem is that SearchView
needs a CursorAdapter
and you are retrieving data from the server, not the database.
问题是SearchView需要一个CursorAdapter,您正在从服务器检索数据,而不是数据库。
However, I have done something like this before with these steps:
然而,我以前就做过这样的事情:
-
Set up your
SearchView
to use aCursorAdapter
;设置SearchView以使用CursorAdapter;
searchView.setSuggestionsAdapter(new SimpleCursorAdapter( context, android.R.layout.simple_list_item_1, null, new String[] { SearchManager.SUGGEST_COLUMN_TEXT_1 }, new int[] { android.R.id.text1 }));
-
Create an
AsyncTask
to read the JSON data from your server and create aMatrixCursor
from the data:创建一个AsyncTask从服务器读取JSON数据,并从数据中创建一个MatrixCursor:
public class FetchSearchTermSuggestionsTask extends AsyncTask<String, Void, Cursor> { private static final String[] sAutocompleteColNames = new String[] { BaseColumns._ID, // necessary for adapter SearchManager.SUGGEST_COLUMN_TEXT_1 // the full search term }; @Override protected Cursor doInBackground(String... params) { MatrixCursor cursor = new MatrixCursor(sAutocompleteColNames); // get your search terms from the server here, ex: JSONArray terms = remoteService.getTerms(params[0]); // parse your search terms into the MatrixCursor for (int index = 0; index < terms.length(); index++) { String term = terms.getString(index); Object[] row = new Object[] { index, term }; cursor.addRow(row); } return cursor; } @Override protected void onPostExecute(Cursor result) { searchView.getSuggestionsAdapter().changeCursor(result); } }
-
Set an
OnQueryTextListener
to kick off your remote server task or start your search activity:设置一个OnQueryTextListener以启动远程服务器任务或启动搜索活动:
searchView.setOnQueryTextListener(new OnQueryTextListener() { @Override public boolean onQueryTextChange(String query) { if (query.length() >= SEARCH_QUERY_THRESHOLD) { new FetchSearchTermSuggestionsTask().execute(query); } else { searchView.getSuggestionsAdapter().changeCursor(null); } return true; } @Override public boolean onQueryTextSubmit(String query) { // if user presses enter, do default search, ex: if (query.length() >= SEARCH_QUERY_THRESHOLD) { Intent intent = new Intent(MainActivity.this, SearchableActivity.class); intent.setAction(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, query); startActivity(intent); searchView.getSuggestionsAdapter().changeCursor(null); return true; } } });
-
Set an
OnSuggestionListener
on theSearchView
to execute your search:在SearchView上设置一个on合理化监听器来执行您的搜索:
searchView.setOnSuggestionListener(new OnSuggestionListener() { @Override public boolean onSuggestionSelect(int position) { Cursor cursor = (Cursor) searchView.getSuggestionsAdapter().getItem(position); String term = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1)); cursor.close(); Intent intent = new Intent(MainActivity.this, SearchableActivity.class); intent.setAction(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, term); startActivity(intent); return true; } @Override public boolean onSuggestionClick(int position) { return onSuggestionSelect(position); } });