20

現在、アプリケーションを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"/>

検索ウィジェットで現在のアクティビティのリストを更新することはできますか?

4

1 に答える 1

46

はい、実際のところ、それが「通常の」使用例です。覚えておく必要があるのは、検索アクション バー ウィジェットを使用するフラグメントは、ウィジェットがそのフラグメントとともに破棄されるため、一般的にそれを登録する部分である必要があるということです。

正しい結び方は次のとおりです。

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 関係者が推奨するベスト プラクティスに従っている場合は、( s とs で s を使用するLoaderManagerのは非常に簡単なはずです...ListActivityListFragments

-ckが必要な場合は、コメントでお気軽に説明を求めてください。

于 2012-03-05T14:23:06.767 に答える