在 Android 4.2 中,我使用 actionBar 选项卡在带有 cursorloaders 和 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) {
}
这是列表片段代码(我省略了第二个片段,因为它本质上是相同的)
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): 致命异常: main 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): at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:560) 04-25 21:36:08.411: E/AndroidRuntime(23013): at 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): at java.lang.reflect.Method.invokeNative(Native Method) 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 /Android 运行时(23013):在 dalvik.system.NativeStart.main(本机方法)