かなり奇妙なエラー(状況)が発生しています。私は多くのListFragment(sqliteデータベースのレコードごとに1つ)でViewPagerとFragmentStatePagerAdapterを使用しています。各ListFragmentは、LoaderManager.LoaderCallbacksを実装します。より重要な部分のみのコードスニペットを表示します(私が理解している限り)
class EnglishDictStatePagerAdapter extends FragmentStatePagerAdapter {
private int records;
private Cursor cursor;
public EnglishDictStatePagerAdapter(FragmentManager fm) {
super(fm);
records = getCursor().getCount();
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new EnglishDictDetailFragment();
getCursor().moveToPosition(position);
long wordId = cursor.getLong(1);
Bundle args = new Bundle();
args.putLong(WORD_ID, wordId);
args.putInt(LANG_TYPE, getCurrentLangType());
args.putInt(WORD_POSITION, position);
fragment.setArguments(args);
closeCursor();
return fragment;
}
private Cursor getCursor() {
if (cursor == null) {
cursor = getContentResolver().query(getContentUri(), getProjection() ,null, null, null);
}
return cursor;
}
private void closeCursor() {
if (cursor != null) {
cursor.close();
}
cursor = null;
}
@Override
public int getCount() {
return records;
}
}
これはListFragmentクラスの一部です
class EnglishDictDetailFragment extends SherlockListFragment implements
LoaderManager.LoaderCallbacks<Cursor> {
private int mLangType;
private int loaderId;
private long mId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.english_dict_list, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
registerForContextMenu(getListView());
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(
getSherlockActivity(),
R.layout.english_dict_list_item,
null,
null,
new int[] { R.id.english_dict_word },
0
);
setListAdapter(mAdapter);
getLoaderManager().initLoader(loaderId, null, this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mId = getArguments().getLong(WORD_ID);
mLangType = getArguments().getInt(LANG_TYPE);
loaderId = getArguments().getInt(WORD_POSITION);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getSherlockActivity(), getContentUri(), null, null, null, null)
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if (loader.getId() == loaderId) {
((SimpleCursorAdapter)getListAdapter()).swapCursor(cursor);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
((SimpleCursorAdapter)getListAdapter()).swapCursor(null);
}
正しいコンテンツがロードされているListFragmentsをスクロールできます。しかし、コードのどこか(たとえば、onContextItemSelected)でカーソルを取得しようとすると、
cursor = (Cursor)getListAdapter().getItem(info.position);
ViewPagerの前または次のListFragmentからカーソルを取得することがよくあります。理由は推測できませんが、onLoadFinishedで、そのメソッドが3回呼び出され、最後に他のListFragmentからのカーソル引数があるときにいくつかのことがわかります。最初は右カーソルを使用してコンテンツを表示しますが、後でオフスクリーンのListFragmentアイテム(隣接)のコンテンツをロードし、隣接するListFragmentからのカーソルがcurrent(visible)ListFragmentのSimpleCursorAdapterに割り当てられると推測できます。誰かが助けることができますか?