アクション バーで SearchView を使用しています。検索ビューでオートコンプリート機能を使用して、データベースから結果を取得したいと考えています。
これは可能ですか?または、カスタム テキスト ボックスを使用して、それにオートコンプリートを追加する必要がありますか?
アクション バーで SearchView を使用しています。検索ビューでオートコンプリート機能を使用して、データベースから結果を取得したいと考えています。
これは可能ですか?または、カスタム テキスト ボックスを使用して、それにオートコンプリートを追加する必要がありますか?
そのため、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);
}
}
を使用した代替方法を次に示し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
オートコンプリート検索ビューでもこの問題に直面していましたが、余分なレイアウトやオートコンプリート テキスト ビューを使用せずに修正しました。 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();
}
});
はい、可能です。提案のために (SQLiteDatabase などで) テーブルを作成し、必要な列でテーブルをフォーマットします。