java - Android:在没有可搜索 Activity 的情况下提供最近的搜索建议?

标签 java android searchview

我有一个 ActionBar SearchView,我可以成功地使用它进行搜索。 android 文档没有解释如何实现搜索建议。我不想有可搜索的 Activity 。

这是我的搜索代码:

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 个类,如下所示

  1. MainActivity - 用于测试 SearchView来自数据库的建议
  2. SuggestionDatabase - 这将存储您最近的搜索关键字。
  3. 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;
        }
    }

}

它是如何工作的

  1. 当用户点击搜索按钮时,onQueryTextSubmit()将被触发,然后搜索关键字将保存在我们的数据库中。假设我们提交了一个关键字“Hello”
  2. 如果用户在 SearchView 中写入字符串,例如“Hel”或“H” onQueryTextChange()将被调用,然后我们在 SQLiteDatabase 中搜索此关键字(SuggestionDatabase)。如果 "Hel"或 "H"与 "Hello"匹配,则通过将返回的 Cursor 设置为 SuggestionSimpleCursorAdapter 来显示查询结果然后将此适配器设置为 SearchView .这是图片。

enter image description here
3. 当然我们会点击“你好”的建议,onSuggestionClick(int position)将为此而呼吁。我们得到 SQLiteCursor来自 SearchView 的对象的适配器( SuggestionSimpleCursorAdapter )并从中获取建议文本,将建议文本设置为 SearchView对象

SQLiteCursor cursor = (SQLiteCursor) searchView.getSuggestionsAdapter().getItem(position);
int indexColumnSuggestion = cursor.getColumnIndex( SuggestionsDatabase.FIELD_SUGGESTION);
searchView.setQuery(cursor.getString(indexColumnSuggestion), false);

如果我们使用 SimpleCursorAdapter它也可以正常工作,但假设我们有这种情况

  1. 如果我们在智能手机上运行此程序并输入关键字“Hel”,建议将正确显示。

enter image description here

  1. 如果我们横向旋转屏幕会怎样?它将切换到全屏模式,您仍然可以输入关键字。

建议会发生什么?一起来看看吧。

enter image description here

看到奇怪的建议了吗?我们如何解决这个问题?通过覆盖 convertToString(Cursor cursor)返回 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(Cursor cursor) ,结果如下

enter image description here

这是数据库

// 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) {

    }

  }

}

我希望这个答案对其他程序员有用。 :)

关于java - Android:在没有可搜索 Activity 的情况下提供最近的搜索建议?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13733460/

相关文章:

android - 如何在 Android 的不同应用程序中使用 Broadcast Receiver?

android - Google Play 控制台显示您的应用与所有设备不兼容的消息

android - 如何更改 SearchView 默认图标?

android - AppCompat 中的 SearchView 会扭曲图标

java - 如何从 Java HttpClient 获取重定向 url

java - ComputeEngine 的 RMI 教程错误

java - 如何使从ListView页中选择一个项目并在下一页/Activity 中以文本显示所选项目成为可能?

java - 在 JTable 中添加 JSpinner 时出现非法参数异常

java - 如何附加到原始文件中的文本?

android-fragments - 使用 ActionBar 选项卡在 ViewPager 中的片段更改时重置 SearchView