1

使用Android 4.2,我使用actionBar選項卡在列表片段之間切換與cursorloaders和sqlite,並且一切正常。我使用ontabreselected回調移回列表的頂部與setSelection(0),它工作,但在屏幕旋轉(方向改變)後崩潰。例如,如果我在列表中向下滾動某個特定位置並旋轉屏幕,該片段會根據需要在相同的位置重新創建,但是如果我重新選擇了帶有setSelection(0)的選項卡,它會以「內容視圖尚未創建「,就好像新的重新創建的視圖與主要活動分離。「內容視圖尚未創建」方向變化ontabreselected,列表片段中的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) { 


} 

這裏是listfragment代碼(I省略第二片段,因爲它本質上是相同的)

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的,其中未經選擇的行307是listeFrg.setSelection(0);

04-25 21:36:08.411:E/AndroidRun時間(23013):致命例外:main 04-25 21:36:08.411:E/AndroidRuntime(23013):java.lang.IllegalStateException:尚未創建的內容視圖 04-25 21:36:08.411:E/AndroidRuntime (23013):at android.app.ListFragment.ensureList(ListFragment.java:386) 04-25 21:36:08.411:E/AndroidRuntime(23013):at android.app.ListFragment.setSelection(ListFragment.java:256 ) 04-25 21:36:08.411:E/AndroidRuntime(23013):at 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):at android.widget.AdapterView.performItemClick(AdapterView.java:298 ) 04-25 21:36:08.411:E/AndroidRuntime(23013):at android.widget.Spinner $ DropdownPopup $ 1.onItemClick(Spinner.java:922) 04-25 21:36:08.411:E/AndroidRuntime 23013):at android.widget.AdapterView.performItemClick(AdapterView.java:298) 04-25 21:36:08.411:E/AndroidRuntime(23013):at android.widget.AbsListView.performItemClick(AbsListView.java:1100) 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):at android.os.Handler.handleCallback(Handler.java:725) 04-25 21:36:08.411:E/AndroidRuntime(23013):at android.os.Handler.dispatchMessage(Handler.java:92) 04-25 21:36:08.411:E/AndroidRuntime(23013):at 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):at java.lang.reflect.Method.invoke(Method.java:511) 04-25 21:36 :08.411:E/AndroidRuntime(23013):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:793) 04-25 21:36:08.411:E/AndroidRuntime(23013):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 04-25 21:36:08.411:E/AndroidRuntime(23013):at dalvik.system.NativeStart。主(本地方法)

回答

0

我想我找到了一個解決方案,我不確定我完全理解爲什麼,但它的工作原理。它涉及修改通過鑄造片段對象以調用setSelection(0)來選擇ontabrelected,如下所示:

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; 

    }  

} 
相關問題