Да, на самом деле, это «нормальный» вариант использования. Что вы должны помнить, так это то, что фрагмент, который использует виджет панели действий поиска, должен быть частью, которая регистрирует его в целом, поскольку виджет будет уничтожен вместе с этим фрагментом.
Вот как правильно завязывать:
в вашем 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
person
ckozl
schedule
05.03.2012