1

在 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(本机方法)

4

1 回答 1

0

我想我找到了一个解决方案,我不确定我是否完全理解为什么,但它确实有效。它涉及通过强制转换片段对象来修改 ontabreselected,以便调用 setSelection(0),如下所示:

 public void onTabReselected(Tab tab, FragmentTransaction ft) {
 int position = tab.getPosition();

  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{
       ListeFragment listeFrg = (ListeFragment)
       getFragmentManager().findFragmentByTag("RECENT");
       listeFrg.setSelection(0);

     }  
        break;
   case 1: 
     if (null == fragmentManager.findFragmentByTag("ALPHA")) {

         ft.replace(R.id.listeFragment, alphaFrg, "ALPHA");
     } else {    
     AlphaListeFragment alphaFrg = (AlphaListeFragment)
      getFragmentManager().findFragmentByTag("ALPHA");
             alphaFrg.setSelection(0);

     }
     break;
    case 2:
     break;

  }    

}
于 2013-05-01T05:02:59.983 回答