Java 安卓:在没有可搜索活动的情况下提供最近的搜索建议?
我有一个ActionBar SearchView,我能够成功地使用它进行搜索。android文档没有解释如何实现搜索建议。我不想有一个可搜索的活动 这是我的搜索代码:Java 安卓:在没有可搜索活动的情况下提供最近的搜索建议?,java,android,searchview,Java,Android,Searchview,我有一个ActionBar SearchView,我能够成功地使用它进行搜索。android文档没有解释如何实现搜索建议。我不想有一个可搜索的活动 这是我的搜索代码: public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_add_song, menu); final SearchView searchView = (SearchView)
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_add_song, menu);
final SearchView searchView = (SearchView) menu.findItem(R.id.song_search).getActionView();
searchView.setFocusable(true);
searchView.setIconified(false);
final AddSongActivity activity = this;
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
// Do nothing
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
// Clear SearchView
searchView.clearFocus();
// Begin Spotify Search
TextView notice = (TextView)findViewById(R.id.search_notice);
URL url;
try {
url = new URL("http://ws.spotify.com/search/1/track.json?q=" + URLEncoder.encode(query,"UTF-8"));
} catch (MalformedURLException e) {
notice.setText("Malformed Search");
notice.setHeight(noticeHeight);
return true;
} catch (UnsupportedEncodingException e) {
notice.setText("Unsupported Encoding. Maybe a problem with your device.");
notice.setHeight(noticeHeight);
return true;
}
new SearchDownload(url, activity).execute();
notice.setText("Loading Tracks");
notice.setHeight(noticeHeight);
Log.i("infodb","" + noticeHeight);
return true;
}
});
这适用于搜索,但我不知道如何实现最近的搜索查询建议。我该怎么做呢
谢谢。好的,我把时间都花在这上面了。我从
SQLiteDatabase
创建了自己的简单的建议实现
我们将创建3个类,如下所示
main活动
-用于测试数据库中的SearchView
建议SuggestionDatabase
-这将存储您最近的搜索关键字SuggestionSimpleCursorAdapter
-这是SimpleCursorAdapter
的子类。我将解释为什么创建这个类而不是使用SimpleCursorAdapter
// MainActivity.java
public class MainActivity
extends Activity
implements SearchView.OnQueryTextListener,
SearchView.OnSuggestionListener
{
private SuggestionsDatabase database;
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
database = new SuggestionsDatabase(this);
searchView = (SearchView) findViewById(R.id.searchView1);
searchView.setOnQueryTextListener(this);
searchView.setOnSuggestionListener(this);
}
@Override
public boolean onSuggestionSelect(int position) {
return false;
}
@Override
public boolean onSuggestionClick(int position) {
SQLiteCursor cursor = (SQLiteCursor) searchView.getSuggestionsAdapter().getItem(position);
int indexColumnSuggestion = cursor.getColumnIndex( SuggestionsDatabase.FIELD_SUGGESTION);
searchView.setQuery(cursor.getString(indexColumnSuggestion), false);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
long result = database.insertSuggestion(query);
return result != -1;
}
@Override
public boolean onQueryTextChange(String newText) {
Cursor cursor = database.getSuggestions(newText);
if(cursor.getCount() != 0)
{
String[] columns = new String[] {SuggestionsDatabase.FIELD_SUGGESTION };
int[] columnTextId = new int[] { android.R.id.text1};
SuggestionSimpleCursorAdapter simple = new SuggestionSimpleCursorAdapter(getBaseContext(),
android.R.layout.simple_list_item_1, cursor,
columns , columnTextId
, 0);
searchView.setSuggestionsAdapter(simple);
return true;
}
else
{
return false;
}
}
}
工作原理
onquerytexsubmit()
,然后搜索关键字将保存在我们的数据库中。假设我们提交一个关键字“Hello”SearchView
中写入字符串,例如“Hel”或“H”,将调用onQueryTextChange()
,然后我们在SQLiteDatabase
(SuggestionDatabase
)中搜索该关键字。如果“Hel”或“H”与“Hello”匹配,则通过在SuggestionSimpleCursorAdapter
中设置返回的光标来显示查询结果,然后在SearchView
中设置此适配器。这是照片李>
3.当然,我们会点击“Hello”的建议,建议点击(int position)就会被调用。我们从
SearchView
的适配器(SuggestionSimpleCursorAdapter
)获取SQLiteCursor
对象,并从中获取建议文本,在SearchView
对象中设置建议文本
SQLiteCursor cursor = (SQLiteCursor) searchView.getSuggestionsAdapter().getItem(position);
int indexColumnSuggestion = cursor.getColumnIndex( SuggestionsDatabase.FIELD_SUGGESTION);
searchView.setQuery(cursor.getString(indexColumnSuggestion), false);
如果我们使用SimpleCursorAdapter
它也可以正常工作,但假设我们有这样的场景
convertToString(光标)
返回CharSequence
// SuggestionSimpleCursorAdapter.java
public class SuggestionSimpleCursorAdapter
extends SimpleCursorAdapter
{
public SuggestionSimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, layout, c, from, to);
}
public SuggestionSimpleCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
@Override
public CharSequence convertToString(Cursor cursor) {
int indexColumnSuggestion = cursor.getColumnIndex(SuggestionsDatabase.FIELD_SUGGESTION);
return cursor.getString(indexColumnSuggestion);
}
}
通过重写convertToString(光标),结果如下
这是数据库
// SuggestionDatabase.java
public class SuggestionsDatabase {
public static final String DB_SUGGESTION = "SUGGESTION_DB";
public final static String TABLE_SUGGESTION = "SUGGESTION_TB";
public final static String FIELD_ID = "_id";
public final static String FIELD_SUGGESTION = "suggestion";
private SQLiteDatabase db;
private Helper helper;
public SuggestionsDatabase(Context context) {
helper = new Helper(context, DB_SUGGESTION, null, 1);
db = helper.getWritableDatabase();
}
public long insertSuggestion(String text)
{
ContentValues values = new ContentValues();
values.put(FIELD_SUGGESTION, text);
return db.insert(TABLE_SUGGESTION, null, values);
}
public Cursor getSuggestions(String text)
{
return db.query(TABLE_SUGGESTION, new String[] {FIELD_ID, FIELD_SUGGESTION},
FIELD_SUGGESTION+" LIKE '"+ text +"%'", null, null, null, null);
}
private class Helper extends SQLiteOpenHelper
{
public Helper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+TABLE_SUGGESTION+" ("+
FIELD_ID+" integer primary key autoincrement, "+FIELD_SUGGESTION+" text);");
Log.d("SUGGESTION", "DB CREATED");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
我希望这个答案对其他程序员很有用。:) 在上述方法中,我注意到一个问题 当用户仅输入一个字符(例如
“H”
)时,在从数据库获取条目并通过searchView.setSuggestionAdapter()
将适配器设置为searchView后,下拉列表不会显示
只有在输入第二个字符(例如,“a”
)后,才会显示建议列表。
还有其他人观察到这种行为吗?在
main活动中,从上面的onCreate方法中的类中首先使用此代码
AutoCompleteTextView search_text = (AutoCompleteTextView) searchView.findViewById(searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null));
search_text.setThreshold(1);
这setThreshold(1)
意味着它现在也可以从一个字符中搜索文本。我的需要更加简单-我不需要数据库,因为我在ArrayList中包含了许多我想要显示的建议
下面是一个示例实现:
import java.util.ArrayList;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.SearchView;
import android.widget.SearchView.OnQueryTextListener;
import android.widget.TextView;
import android.widget.Toast;
public class ActivityTest extends Activity implements OnQueryTextListener {
private static final String COLUMN_ID = "_id";
private static final String COLUMN_TERM = "term";
private static final String DEFAULT = "default";
private SearchManager searchManager;
private SearchView searchView;
private MenuItem searchMenuItem;
private SuggestAdapter suggestionsAdapter;
private final ArrayList<String> suggestionsArray = new ArrayList<String>();
private final ArrayList<String> dummyArray = new ArrayList<String>();
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create some dummy entries
dummyArray.add("apples");
dummyArray.add("oranges");
dummyArray.add("bananas");
dummyArray.add("pears");
dummyArray.add("plums");
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchMenuItem = menu.findItem(R.id.action_search);
searchView = (SearchView) searchMenuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setOnQueryTextListener(this);
final MatrixCursor matrixCursor = getCursor(suggestionsArray);
suggestionsAdapter = new SuggestAdapter(this, matrixCursor, suggestionsArray);
searchView.setSuggestionsAdapter(suggestionsAdapter);
suggestionsAdapter.notifyDataSetChanged();
return true;
}
@Override
public boolean onQueryTextChange(final String newText) {
suggestionsArray.clear();
for (int i = 0; i < dummyArray.size(); i++) {
if (dummyArray.get(i).contains(newText)) {
suggestionsArray.add(dummyArray.get(i));
}
}
final MatrixCursor matrixCursor = getCursor(suggestionsArray);
suggestionsAdapter = new SuggestAdapter(this, matrixCursor, suggestionsArray);
searchView.setSuggestionsAdapter(suggestionsAdapter);
suggestionsAdapter.notifyDataSetChanged();
return true;
}
@Override
public boolean onQueryTextSubmit(final String query) {
// TODO Auto-generated method stub
return false;
}
private class SuggestAdapter extends CursorAdapter implements OnClickListener {
private final ArrayList<String> mObjects;
private final LayoutInflater mInflater;
private TextView tvSearchTerm;
public SuggestAdapter(final Context ctx, final Cursor cursor, final ArrayList<String> mObjects) {
super(ctx, cursor, 0);
this.mObjects = mObjects;
this.mInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View newView(final Context ctx, final Cursor cursor, final ViewGroup parent) {
final View view = mInflater.inflate(R.layout.list_item_search, parent, false);
tvSearchTerm = (TextView) view.findViewById(R.id.tvSearchTerm);
return view;
}
@Override
public void bindView(final View view, final Context ctx, final Cursor cursor) {
tvSearchTerm = (TextView) view.findViewById(R.id.tvSearchTerm);
final int position = cursor.getPosition();
if (cursorInBounds(position)) {
final String term = mObjects.get(position);
tvSearchTerm.setText(term);
view.setTag(position);
view.setOnClickListener(this);
} else {
// Something went wrong
}
}
private boolean cursorInBounds(final int position) {
return position < mObjects.size();
}
@Override
public void onClick(final View view) {
final int position = (Integer) view.getTag();
if (cursorInBounds(position)) {
final String selected = mObjects.get(position);
Toast.makeText(getApplicationContext(), selected, Toast.LENGTH_SHORT).show();
// Do something
} else {
// Something went wrong
}
}
}
private MatrixCursor getCursor(final ArrayList<String> suggestions) {
final String[] columns = new String[] { COLUMN_ID, COLUMN_TERM };
final Object[] object = new Object[] { 0, DEFAULT };
final MatrixCursor matrixCursor = new MatrixCursor(columns);
for (int i = 0; i < suggestions.size(); i++) {
object[0] = i;
object[1] = suggestions.get(i);
matrixCursor.addRow(object);
}
return matrixCursor;
}
}
import java.util.ArrayList;
导入android.app.Activity;
导入android.app.SearchManager;
导入android.content.Context;
导入android.database.Cursor;
导入android.database.MatrixCursor;
导入android.os.Bundle;
导入android.view.LayoutInflater;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.view.ViewGroup;
导入android.widget.CursorAdapter;
导入android.widget.SearchView;
导入android.widget.SearchView.OnQueryTextListener;
导入android.widget.TextView;
导入android.widget.Toast;
公共类ActivityTest在QueryTextListener上扩展活动实现{
私有静态最终字符串列_ID=“_ID”;
私有静态最终字符串列\u TERM=“TERM”;
私有静态最终字符串DEFAULT=“DEFAULT”;
私人搜索管理器搜索管理器;
私有搜索视图搜索视图;
私有菜单项搜索菜单项;
私有建议适配器建议适配器;
private final ArrayList SuggestionArray=新ArrayList();
私有最终ArrayList dummyArray=新ArrayList();
@凌驾
创建时受保护的void(最终捆绑包savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建一些虚拟条目
添加(“苹果”);
添加(“橙子”);
添加(“香蕉”);
添加(“梨”);
添加(“李子”);
}
@凌驾
公共布尔onCreateOptions菜单(最终菜单){
getMenuInflater().充气(R.menu.main,menu);
searchManager=(searchManager)getSystemService(Context.SEARCH\u服务);
searchMenuItem=menu.findItem(R.id.action\u search);
searchView=(searchView)searchMenuItem.getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName());
setOnQueryTextListener(这个);
最终MatrixCursor MatrixCursor=getCursor(SuggestionArray);
SuggestionAdapter=新的SuggestionAdapter(this、matrixCursor、SuggestionArray);
searchView.setSuggestionAdapter(SuggestionAdapter);
suggestionsAdapter.notifyDataSetChanged();
返回true;
}
@凌驾
公共布尔onQueryTe
@Override
public void onDataReceived(final ArrayList<String> results) {
suggestionsArray.clear();
suggestionsArray.addAll(results);
final MatrixCursor matrixCursor = getCursor(suggestionsArray);
suggestionsAdapter = new SuggestAdapter(this, matrixCursor, suggestionsArray);
searchView.setSuggestionsAdapter(suggestionsAdapter);
suggestionsAdapter.notifyDataSetChanged();
}