5

Android開発者のブログエントリに従って、actionbarcompat(Androidサポートライブラリを使用)を使用しようとしています。

基本的に、ListFragment を拡張する Fragment を作成しようとしています。リストビューに ArrayAdapter を使用しています。アクションバーの互換性を検索メニュー項目とうまく統合することができ、検索も機能させることができました。

向きの変更時にもフラグメントの状態を保持したいと考えています。フラグメントに setRetainInstance(true) を設定していません。検索ビューの状態を保持するために、次のことを試しました。

  • テキストを onSaveInstanceState() の SearchView に保存します。
  • onCreateView で、使用可能な場合は searchText を取得します
  • onCreateOptionsMenu (向きが変わるたびに呼び出される) で、検索クエリを SearchView インスタンスに設定しようとしています。mSearchView.setQuery(mSearchText, false);

このアプローチには 2 つの問題があります。

  1. onQueryTextChange() は、向きの変更時に 2 回呼び出されます。1 回目は保持されている searchText を使用して (理由によりmSearchView.setQuery(mSearchText, false);)、もう 1 回は空の文字列値を使用して呼び出されます。空の String 値を使用したこの 2 番目の呼び出しは、リスト アダプタを更新して、フィルタリングなしですべての項目を取得します。また、なぜこれが起こっているのかよくわかりません。
  2. mSearchView.setQuery(mSearchText, false);SearchView でクエリを設定しておらず、UI にも表示されません (向きを変更すると、デフォルトで検索ビューが展開され、クエリを設定してもテキスト値なしでフォーカスされます)。

私のフラグメントの概要は次のとおりです。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // create and initialize list adapter
    ....
    setHasOptionsMenu(true);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.plainlist, container, false);
    if (savedInstanceState != null) {
        mSearchText = savedInstanceState.getString(RetainDataKeySearchText, null);
    }
    return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    if (isAdded()) {
        if (mSearchView != null) {
            String searchText = mSearchView.getQuery().toString();
            if (!TextUtils.isEmpty(searchText))
                outState.putString(RetainDataKeySearchText, searchText);
            }
        }
    super.onSaveInstanceState(outState);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.search_item_list, menu);
    MenuItem searchItem = menu.findItem(R.id.menu_search);
    mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    mSearchView.setOnQueryTextListener(this);

    if (!TextUtils.isEmpty(mSearchText))
        mSearchView.setQuery(mSearchText, false);

    super.onCreateOptionsMenu(menu, inflater);
}

@Override
public boolean onQueryTextChange(String newText) {
    // Called when the action bar search text has changed.
    searchItems(newText);
    return true;
}

@Override
public boolean onQueryTextSubmit(String searchText) {
    return true;
}

private void searchItems(String searchText) {
    // filter results and update the list adapter
}

メニュー xml (search_item_list) ファイルは次のとおりです。

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

    <item android:id="@+id/menu_search"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/search"
        android:orderInCategory="0"
        sprinklr:showAsAction="ifRoom|collapseActionView"
        sprinklr:actionViewClass="android.support.v7.widget.SearchView" />

</menu>

不足しているものがあるかどうか、またはandroid.support.v7.widget.SearchViewactionbarcompat を使用した ListFragment の向きの変更時に SearchView () の状態を保持するためのより良い代替手段があるかどうかを知りたいです。

4

2 に答える 2

2

回避策として、

mSearchView.setQuery(mSearchText, false); 

と:

final String s = mSearchText;

mSearchView.post(new Runnable() {

    @Override
    public void run() {
        mSearchView.setQuery(s, false);
    }
});

システムが空の文字列を設定した後、保存された文字列を設定します。

于 2014-06-02T14:55:35.390 に答える