24

ActionBar SearchView があり、それを使用して検索を正常に行うことができます。Android のドキュメントには、検索候補を実装する方法が説明されていません。私は検索可能な活動をしたくありません。

これは私の検索コードです:

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;
            }
        });

これは検索には機能しますが、最近の検索クエリの提案を実装する方法がわかりません。どうすればこれを行うことができますか?

ありがとうございました。

4

4 に答える 4

56

わかりました、私はこれに時間を費やしました。から独自の簡単な提案の実装を作成しSQLiteDatabaseます。

次のような 3 つのクラスを作成します。

  1. MainActivitySearchView-データベースからの提案のテスト用
  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. ユーザーが "Hel" や "H" などの文字列を に書き込むと、SearchViewonQueryTextChange()呼び出され、このキーワードをSQLiteDatabase( SuggestionDatabase) で検索します。"Hel" または "H" が "Hello" に一致する場合は、返された Cursor を に設定してクエリの結果を表示しSuggestionSimpleCursorAdapter、次にこのアダプターを に設定しSearchViewます。これが写真です。

ここに画像の説明を入力
3. もちろん、「こんにちは」という提案をタップonSuggestionClick(int position)します。そのために呼び出されます。のアダプタ ( )SQLiteCursorからオブジェクトを取得し、そこから提案テキストを取得して、提案テキストをオブジェクトに設定します。SearchViewSuggestionSimpleCursorAdapterSearchView

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

使用SimpleCursorAdapterしても適切に機能しますが、このシナリオがあるとしましょう

  1. このプログラムをスマートフォンで実行し、キーワード「Hel」を入力すると、候補が適切に表示されます。

ここに画像の説明を入力

  1. 画面を横向きに回転させたらどうなりますか? 全画面モードに切り替わり、引き続きキーワードを入力できます。

提案ではどうなりますか?見てみましょう。

ここに画像の説明を入力

奇妙な提案を参照してください。どうやってそれを解決しますか?convertToString(Cursor cursor)を返す which をオーバーライドすることにより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)すると、結果は次のようになります

ここに画像の説明を入力

そしてデータベースはこちら

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

    }

  }

}

この回答が他のプログラマーに役立つことを願っています。:)

于 2012-12-08T01:45:31.230 に答える
-1

上記のアプローチで気付いた問題が 1 つあります。

"H"DB からエントリを取得し、アダプターを 経由で searchView に設定した後、ユーザーが 1 文字 (例: ) だけを入力するsearchView.setSuggestionsAdapter(<adapter>)と、ドロップダウン リストが表示されません。

2 番目の文字 (例: " ", "a") を入力した後にのみ、候補リストが表示されます。他の誰かがこの動作を観察していますか?

于 2012-12-20T00:05:43.407 に答える