Android 4.2 では、actionBar タブを使用して、カーソルローダーと sqlite を使用してリスト フラグメントを切り替えていますが、すべて正常に動作します。ontabreselected コールバックを使用して、setSelection(0) でリストの先頭に戻ります。これは機能しますが、画面の回転 (向きの変更) 後にクラッシュします。たとえば、リストを特定の位置で下にスクロールして画面を回転させると、フラグメントは目的の同じ位置に再作成されますが、setSelection(0) で上部に移動するタブを再選択すると、"新しく再作成されたビューがメイン アクティビティから切り離されているかのように、コンテンツ ビューはまだ作成されていません。
私の主な活動は ActionBar.TabListener を実装しています
public class RestonetActivity extends Activity implements ListItemSelectListener, ActionBar.TabListener{
private boolean useLogo = false;
private boolean showHomeUp = true;
private int tab_pos;
ListeFragment listeFrg = new ListeFragment();
AlphaListeFragment alphaFrg = new AlphaListeFragment();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar ab = getActionBar();
ab.setDisplayUseLogoEnabled(useLogo);
ab.setDisplayShowHomeEnabled(true);
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ab.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
if (savedInstanceState != null){
tab_pos = savedInstanceState.getInt("tabState");
ab.addTab(ab.newTab().setText(R.string.tab_recente).setTabListener(this),0,false);
ab.addTab(ab.newTab().setText(R.string.tab_alpha).setTabListener(this),1,false);
ab.addTab(ab.newTab().setText(R.string.tab_fortes).setTabListener(this),2,false);
ab.setSelectedNavigationItem(tab_pos);
} else {
ab.addTab(ab.newTab().setText(R.string.tab_recente).setTabListener(new TabListener<ListeFragment>(this,"recente",ListeFragment.class)));
ab.addTab(ab.newTab().setText(R.string.tab_recente).setTabListener(this),0,true);
ab.addTab(ab.newTab().setText(R.string.tab_alpha).setTabListener(this),1,false);
ab.addTab(ab.newTab().setText(R.string.tab_fortes).setTabListener(this),2,false);
}
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
int position = tab.getPosition();
Log.e ("ontabreselected", "pos= "+position);
FragmentManager fragmentManager = getFragmentManager();
// position cursor at top of list if user retaps a tab
switch (position) {
case 0:
if (null == fragmentManager.findFragmentByTag("RECENT")) {
ft.replace(R.id.listeFragment, listeFrg, "RECENT");
}
else{
listeFrg.setSelection(0);
}
break;
case 1:
if (null == fragmentManager.findFragmentByTag("ALPHA")) {
ft.replace(R.id.listeFragment, alphaFrg, "ALPHA");
} else {
alphaFrg.setSelection(0);
}
break;
case 2:
break;
}
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
FragmentManager fragmentManager = getFragmentManager();
int position = tab.getPosition();
int loaderID = 0;
String fragmentTag;
switch (position) {
case 0:
loaderID=RESTO_RECENT_LOADER;
if (null == fragmentManager.findFragmentByTag("RECENT")) {
ft.replace(R.id.listeFragment, listeFrg, "RECENT");
}
break;
case 1:
loaderID=RESTO_ALPHA_LOADER;
if (null == fragmentManager.findFragmentByTag("ALPHA")) {
ft.replace(R.id.listeFragment, alphaFrg, "ALPHA");
}
break;
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
リストフラグメントコードは次のとおりです(2番目のフラグメントは本質的に同一であるため省略しました)
public class ListeFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private ListItemSelectListener listeSelectListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.e ("onAttach", "ListeFragment Attached ");
try {
listeSelectListener = (ListItemSelectListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " doit implementer ListItemSelectListener");
}
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
listeSelectListener.onItemSelected(position, id);
}
private static final int RESTO_RECENT_LOADER = 0x01;
private static final int RESTO_ALPHA_LOADER = 0x02;
private static final int RESTO_HIGH_LOADER = 0x03;
private static final int RESTO_SEARCH_LOADER = 0x04;
private SimpleCursorAdapter adapter;
public void afficheList(int loader_id, String query) {
Bundle mBundle = new Bundle();
mBundle.putString("search_query", query);
getLoaderManager().restartLoader(loader_id, mBundle, this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] uiBindFrom = { RestoDatabase.COL_ETAB, RestoDatabase.COL_MONTANT };
int[] uiBindTo = { R.id.TextView01, R.id.Montant };
adapter = new SimpleCursorAdapter(
getActivity(), R.layout.row,
null, uiBindFrom, uiBindTo,
CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
}
@Override
public void onResume()
{
super.onResume();
// call initLoader on Resume avoids a bug which calls onLoadFinished twice
LoaderManager lm = getLoaderManager();
lm.initLoader(RESTO_RECENT_LOADER, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { RestoDatabase.ID, RestoDatabase.COL_ETAB, RestoDatabase.COL_MONTANT };
switch (id){
case RESTO_RECENT_LOADER:
return new CursorLoader(getActivity(),
RestoProvider.CONTENT_URI, projection, null, null, date_infraction DESC");
case RESTO_ALPHA_LOADER:
return new CursorLoader(getActivity(),
RestoProvider.CONTENT_URI_GROUPBY, projection, null, null,"etablissement ASC");
default: return null;
}
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
最後に、これが logcat です。untabreselected の 307 行目は 次のとおりですlisteFrg.setSelection(0);
。
04-25 21:36:08.411: E/AndroidRuntime(23013): 致命的な例外: メイン 04-25 21:36:08.411: E/AndroidRuntime(23013): java.lang.IllegalStateException: コンテンツ ビューがまだ作成されていません 04-25 21:36:08.411: E/AndroidRuntime(23013): android.app.ListFragment.ensureList(ListFragment.java:386) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.app.ListFragment で.setSelection (ListFragment.java:256) 04-25 21:36:08.411: E/AndroidRuntime (23013): ca.usimage.resto.RestonetActivity.onTabReselected (RestonetActivity.java:307) 04-25 21:36:08.411 : E/AndroidRuntime(23013): com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:560) 04-25 21:36:08.411: E/AndroidRuntime(23013): com.android.internal. app.ActionBarImpl$TabImpl.select(ActionBarImpl.java:1067) 04-25 21:36:08.411: E/AndroidRuntime(23013): com.android.internal.widget.ScrollingTabContainerView.onItemClick(ScrollingTabContainerView.java:355) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.widget.AdapterView.performItemClick(AdapterView.java:298) 04-25 21: 36:08.411: E/AndroidRuntime(23013): android.widget.Spinner$DropdownPopup$1.onItemClick(Spinner.java:922) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.widget. AdapterView.performItemClick(AdapterView.java:298) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.widget.AbsListView.performItemClick(AbsListView.java:1100) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.widget.AbsListView$PerformClick.run(AbsListView.java:2749) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.widget.AbsListView$1.run( AbsListView.java:3423) 04-25 21:36:08.411: E/AndroidRuntime(23013): Android で。os.Handler.handleCallback(Handler.java:725) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.os.Handler.dispatchMessage(Handler.java:92) 04-25 21:36: 08.411: E/AndroidRuntime(23013): android.os.Looper.loop(Looper.java:137) 04-25 21:36:08.411: E/AndroidRuntime(23013): android.app.ActivityThread.main(ActivityThread) .java:5039) 04-25 21:36:08.411: E/AndroidRuntime(23013): java.lang.reflect.Method.invokeNative(ネイティブ メソッド) 04-25 21:36:08.411: E/AndroidRuntime(23013) : java.lang.reflect.Method.invoke(Method.java:511) 04-25 21:36:08.411: E/AndroidRuntime(23013): com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit) .java:793) 04-25 21:36:08.411: E/AndroidRuntime (23013): com.android.internal.os.ZygoteInit.main (ZygoteInit.java:560) 04-25 21:36:08.411: E /AndroidRuntime(23013):dalvik.system.NativeStart.main (ネイティブ メソッド) で