Как обновить ListView в ListFragment из FragmentActivity?

Я использую ListFragment внутри FragmentActivity вместе с SimpleCursorAdapter и модифицированным CursorLoader. Измененный CursorLoader просто выдает rawQueries - никаких других изменений.

В какой-то момент в FragmentActivity мне нужно восстановить данные/курсор, который передает ListView в ListFragment.

Как я могу это сделать?

Большое спасибо заранее.

Здесь FragmentActivity вызывает метод в ListFragment:

public class ActivityList extends FragmentActivity {

    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        ...
        processUpdateList();
    }

    ...

    private void processUpdateList() {
        Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragmentlist);
        if (fragment != null) {
            ((FragmentList) fragment).requeryList();
        }
    }
}

И здесь ListFragment с методом, который должен инициировать повторный запрос, перезагрузить или перекрасить ListView. ListView.invalidate() не помог - он не изменил показанные данные.

public class FragmentList extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

    private SimpleCursorAdapter adapter;
    private Context             context;
    private ListView            listView;

    public void requeryList() {
    // listView.invalidate(); didn't re-query
        // TODO: How???
    }

    @Override
    public void onActivityCreated(final Bundle bundle) {
        super.onActivityCreated(bundle);

        context = getActivity().getApplicationContext();

        listView = getListView();

        getActivity().getSupportLoaderManager().initLoader(MyConstants.LDR_TABLE1LIST, null, this);

        adapter = new SimpleCursorAdapter(context,
                                          R.layout.fragmentlist_row,
                                          null,
                                          new String[] { Table1.DESCRIPTION },
                                          new int[] { R.id.fragmentlist_row_description },
                                          CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        setListAdapter(adapter);
        setListShown(false);

        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    }

    @Override
    public Loader<Cursor> onCreateLoader(final int id, final Bundle bundle) {
        MyCursorLoader loader = null;

        switch (id) {
            case MyConstants.LDR_TABLE1LIST:
                loader = new MyCursorLoader(context,
                                            MySQLiteOpenHelper.TABLE1_FETCH,
                                            null);
                break;
        }

        return loader;
    }

    @Override
    public void onLoaderReset(final Loader<Cursor> loader) {
        adapter.swapCursor(null);
    }

    @Override
    public void onLoadFinished(final Loader<Cursor> loader, final Cursor cursor) {
        adapter.swapCursor(cursor);

        setListShown(true);
    }
}

Ответ 1

Попробуйте вызвать метод restartLoader(MyConstants.LDR_TABLE1LIST, null, this); LoaderManager только в вашем методе requeryList().

Ответ 2

Вам не нужно вызывать notifyDataSetChanged(): загрузчик позаботится об этом для вас. Ваш код выглядит неплохо; Я сразу не вижу ничего плохого. Для справки, я предлагаю вам сравнить свой код с com.example.android.apis.app/LoaderThrottle.java в примере приложения API Demos.

Ответ 3

Погрузчики будут по возможности использовать курсор. Если вы запрашиваете загрузчик для набора данных, который не изменился, загрузчик является интеллектуальным и возвращает курсор через onLoadFinished без какой-либо дополнительной работы, даже не устанавливая положение курсора на -1.

Попробуйте вызвать Cursor.moveToPosition(-1) в onLoadFinished(), чтобы обойти эту проблему.