現在、アプリケーションを左側にListFragment
、右側にDetailsFragment
を設定しています(下のタブレットのレイアウトと同様)。
アクションバーには、検索用語が送信されたときにリストの内容を更新する検索ウィジェットがあります(ListFragment内)。 Android dev( http://developer.Android.com/guide/topics/search/search-dialog.html ))の検索ガイドに従っていますが同じアクティビティでリストを更新するための検索を取得する際に問題が発生します。
検索語が送信されたときに新しいアクティビティを呼び出すことで、なんとか実装を機能させることができましたが、これにより、戻るボタンの動作がおかしくなります(つまり、押し戻すと、検索ウィジェットに検索語が表示されたまま前のアクティビティに移動します) )。
次のようにマニフェストにインテントラインを追加しました
<intent-filter>
<action Android:name="Android.intent.action.SEARCH" />
</intent-filter>
<meta-data Android:name="Android.app.searchable"
Android:resource="@xml/searchable"/>
検索ウィジェットを取得して、現在のアクティビティのリストを更新することはできますか?
はい、実際のところ、これは「通常の」ユースケースです。覚えておく必要があるのは、検索アクションバーウィジェットを使用するフラグメントは、ウィジェットがそのフラグメントとともに破棄されるため、一般にそれを登録する部分である必要があるということです。
適切に結び付ける方法は次のとおりです。
ListFragment
に、オプションメニュー項目があることを知らせます...
_@Override
public void onActivityCreated(Bundle savedInstanceState) {
..
setHasOptionsMenu(true);
..
}
_
次に、同じListFragment
内で、コールバックをオーバーライドしてオプションメニューを作成します。SearchViewウィジェット参照を取得したら、QueryTextListenerコールバックを登録します。
_@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.grid_default, menu);
SearchView searchView = (SearchView)menu.findItem(R.id.grid_default_search).getActionView();
searchView.setOnQueryTextListener(queryListener);
}
_
プログラム(Java)または宣言(XML)のいずれかを介して検索ウィジェットを作成します。ここにXML(上からgrid_default.xmlという名前)があります。
_<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item
Android:id="@+id/grid_default_search"
Android:icon="@Android:drawable/ic_menu_search"
Android:title="search"
Android:showAsAction="always"
Android:actionViewClass="Android.widget.SearchView"
/>
<!-- other items or whatever -->
</menu>
_
ここで、ListFragment
に戻り、上記で登録したqueryListener
を作成する必要があります。
_private String grid_currentQuery = null; // holds the current query...
final private OnQueryTextListener queryListener = new OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
getActivity().getActionBar().setSubtitle("List");
grid_currentQuery = null;
} else {
getActivity().getActionBar().setSubtitle("List - Searching for: " + newText);
grid_currentQuery = newText;
}
getLoaderManager().restartLoader(0, null, MyListFragment.this);
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
Toast.makeText(getActivity(), "Searching for: " + query + "...", Toast.LENGTH_SHORT).show();
return false;
}
};
_
これで、クエリが変更または送信されたときにわかりました。私の例では、データベースが小さくて結果が速いため、キーが押されるたびに再クエリを実行します。これを変更する必要があるかもしれません。ウィジェットを使用してListFragment
内のプライベートクラスフィールドを検索ウィジェットの現在のテキスト(_grid_currentQuery
_)に設定し、getLoaderManager().restartLoader(0, null, MyListFragment.this);
を呼び出しています。onCreateLoader
内で更新しています。私がこのように使用したクエリ:
_@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bargs) {
String sort = "SortColumn ASC";
String[] grid_columns = new String[] { "ColumnA", "ColumnB", "Etc..." };
String grid_whereClause = "ColumnToSearchBy LIKE ?"
if (!TextUtils.isEmpty(grid_currentQuery)) {
return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, grid_whereClause, new String[] { grid_currentQuery + "%" }, sort);
}
return new CursorLoader(getActivity(), DataProvider.CONTENT_URI, grid_columns, null, null, sort);
}
_
本当に必要なのはそれだけです。これはちょっと切り刻まれていると思いますが、アダプターを設定し、最初にgetLoaderManager().initLoader(0, null, this);
を使用してローダーを起動する必要があるため、このようになっています。そして、処理する必要のある残りのすべてのローダーコールバック...しかし、Androidの人々によって定められたベストプラクティスに従っている場合(LoaderManager
sとListActivity
sでListFragments
sを使用するあなたにとってかなり簡単に...
-ckが必要な場合は、コメントで説明を求めてください。