42

アクション バーで SearchView を使用しています。検索ビューでオートコンプリート機能を使用して、データベースから結果を取得したいと考えています。

これは可能ですか?または、カスタム テキスト ボックスを使用して、それにオートコンプリートを追加する必要がありますか?

4

7 に答える 7

41

そのため、v7 バージョンでこれを行う必要があり、ArrayAdapter を使用してアダプターを単純に設定できないことがわかり、がっかりしました。

ストックの AutoCompleteTextView を使用したくありませんでした (ここでトップのコメンターが行っているように)。これは、小さな検索アイコンや x ボタンなど、SearchView の多くのおしゃれな機能を見逃しているためです。

だから私は SearchView を拡張し、これを得ました:

public class ArrayAdapterSearchView extends SearchView {

private SearchView.SearchAutoComplete mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (SearchAutoComplete) findViewById(android.support.v7.appcompat.R.id.search_src_text);
    this.setAdapter(null);
    this.setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    // don't let anyone touch this
}

public void setOnItemClickListener(OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}

次のように、ActionBar のメニュー xml でこれを使用できます。

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto" >

<item
    android:id="@+id/action_search"
    android:icon="@android:drawable/ic_menu_add"
    android:title="TITLE"
    app:actionViewClass="com.yourpackage.ArrayAdapterSearchView"
    app:showAsAction="ifRoom|collapseActionView"/>

</menu>

オートコンプリート リストにクリック機能を追加することもできます (たとえば、テキストを EditText に設定します)。

MenuItem searchItem = menu.findItem(R.id.action_search);
final ArrayAdapterSearchView searchView = (ArrayAdapterSearchView)searchItem.getActionView();
searchView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        searchView.setText(adapter.getItem(position).toString());

    }
});

そして、これは通常の古い android.widget.SearchView の同様のバージョンです。

public class ArrayAdapterSearchView extends SearchView {

private AutoCompleteTextView mSearchAutoComplete;

public ArrayAdapterSearchView(Context context) {
    super(context);
    initialize();
}

public ArrayAdapterSearchView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
    mSearchAutoComplete = (AutoCompleteTextView) findViewById(getResources().getIdentifier("android:id/search_src_text", null, null));
    setAutoCompleSuggestionsAdapter(null);
    setOnItemClickListener(null);
}

@Override
public void setSuggestionsAdapter(CursorAdapter adapter) {
    throw new UnsupportedOperationException("Please use setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) instead");
}

public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
    mSearchAutoComplete.setOnItemClickListener(listener);
}

public void setAutoCompleSuggestionsAdapter(ArrayAdapter<?> adapter) {
    mSearchAutoComplete.setAdapter(adapter);
}

public void setText(String text) {
    mSearchAutoComplete.setText(text);
}

}
于 2013-11-15T00:01:40.127 に答える
8

を使用した代替方法を次に示しCursorAdapterます。

ExampleActivity.java

private Menu menu;

@Override
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.example, menu);

    this.menu = menu;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setOnQueryTextListener(new OnQueryTextListener() { 

            @Override 
            public boolean onQueryTextChange(String query) {

                loadHistory(query);

                return true; 

            } 

        });

    }

    return true;

}

// History
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void loadHistory(String query) {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        Cursor cursor = db.rawQuery("SELECT * FROM items", null); // Example database query

        SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        final SearchView search = (SearchView) menu.findItem(R.id.search).getActionView();

        search.setSearchableInfo(manager.getSearchableInfo(getComponentName()));

        search.setSuggestionsAdapter(new ExampleAdapter(this, cursor, items));

    }

}

次に、から拡張されたアダプターを作成する必要がありますCursorAdapter

ExampleAdapter.java

public class ExampleAdapter extends CursorAdapter {

    private List<String> items;

    private TextView text;

    public ExampleAdapter(Context context, Cursor cursor, List<String> items) {

        super(context, cursor, false);

        this.items = items;

    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {

        text.setText(cursor.getString(cursor.getColumnIndex("text"))); // Example column index

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = inflater.inflate(R.layout.item, parent, false);

        text = (TextView) view.findViewById(R.id.text);

        return view;

    }

}

注: インポートするときCursorAdapterは、Android サポート バージョンをインポートせず、android.widget.CursorAdapter代わりに標準をインポートしてください。

アダプタには、カスタム レイアウトも必要です。

res/レイアウト/item.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView
        android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

追加のテキスト ビューまたはイメージ ビューをレイアウトに追加し、それらにアダプターのデータを入力することで、リスト アイテムをカスタマイズできるようになりました。次に、SearchView メニュー項目が必要です。

res/menu/example.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/search"
        android:title="@string/search"
        android:showAsAction="ifRoom"
        android:actionViewClass="android.widget.SearchView" />

</menu>

次に、検索可能な構成を作成します。

res/xml/searchable.xml

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="@string/search" >
</searchable>

最後に、マニフェスト ファイルの関連するアクティビティ タグ内にこれを追加します。

AndroidManifest.xml

<intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>

<meta-data
    android:name="android.app.default_searchable"
    android:value="com.example.ExampleActivity" />
<meta-data
    android:name="android.app.searchable"
    android:resource="@xml/searchable" />

注意:例で使用される文字列は、 values/strings.xml@string/searchで定義する必要があります。プロジェクトの参照を更新することも忘れないでください。com.example

参照用の元のチュートリアルは次のとおりです。

http://tpbapp.com/android-development/android-action-bar-searchview-tutorial

于 2014-03-16T03:35:10.763 に答える
8

オートコンプリート検索ビューでもこの問題に直面していましたが、余分なレイアウトやオートコンプリート テキスト ビューを使用せずに修正しました。 SearchAutoCompleteというクラスがあります。これを使用してオートコンプリート機能を実現しました。検索ビューで提案するアイテムの ArrayList を含む単純なリストアダプターを配置するだけです。アダプターをSearchAutoCompleteに設定すると、オートコンプリート機能が以下のコードで動作します。カスタム レイアウトを追加する必要はありません。onCreateOptionsMenu(...) メソッドを私のコードに置き換えるだけです:

    @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);

MenuItem searchItem = menu.findItem(R.id.search);
SearchView mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);

SearchAutoComplete searchAutoComplete = (SearchAutoComplete)     mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, itemArrayList);
searchAutoComplete.setAdapter(adapter);

SearchManager searchManager =
(SearchManager) getSystemService(this.SEARCH_SERVICE);
mSearchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
return true;
}

提案されたアイテムをクリックすると、そのアイテムが検索ビューに表示されるはずなので、アダプタを onCreateOptionmenu(...) メソッド内で searchAutoComplete に設定した直後に以下のコードを追加します

  searchAutoComplete.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
    // TODO Auto-generated method stub

    String searchString=(String)parent.getItemAtPosition(position);
    searchAutoComplete.setText(""+searchString);
    Toast.makeText(MainActivity.this, "you clicked "+searchString, Toast.LENGTH_LONG).show();

    }
    });
于 2015-11-14T13:16:57.680 に答える
6

はい、可能です。提案のために (SQLiteDatabase などで) テーブルを作成し、必要な列でテーブルをフォーマットします。

このリンクを参照してください

于 2013-04-04T07:20:21.373 に答える