2012-05-08 268 views
12

我正在使用ActionBarSherlock在我的應用程序中實現帶有選項卡的ActionBar。 當我啓動應用程序,並從標籤切換到標籤,一切都很好。但是,當我從縱向模式更改爲橫向模式時,上次激活的選項卡的內容保持可見。更改爲其他選項卡會導致在舊內容的頂部繪製新內容(請參閱圖像)。在方向更改後更改選項卡後,選項卡內容保持可見狀態

enter image description here

我的主類:

public class TreinVerkeer extends SherlockFragmentActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setupTabs(savedInstanceState); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getSupportMenuInflater(); 
     inflater.inflate(R.menu.menu, menu); 
     return true; 
    } 

    private void setupTabs(Bundle savedInstanceState) { 
     ActionBar actionBar = getSupportActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     Tab tab = actionBar.newTab().setText("STATIONS").setTabListener(new TabListener<StationsFragment>(this, "stations", StationsFragment.class)); 
     actionBar.addTab(tab); 

     tab = actionBar.newTab().setText("ROUTE").setTabListener(new TabListener<RouteFragment>(this, "route", RouteFragment.class)); 
     actionBar.addTab(tab); 

     tab = actionBar.newTab().setText("DELAYS").setTabListener(new TabListener<DelaysFragment>(this, "delays", DelaysFragment.class)); 
     actionBar.addTab(tab); 

     if (savedInstanceState != null) { 
      actionBar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex()); 
    } 
} 

的TabListener(從"Adding Navigations Tabs" on the Android developer site進行一些小改動):

public class TabListener<T extends SherlockFragment> implements com.actionbarsherlock.app.ActionBar.TabListener { 
    private SherlockFragment mFragment; 
    private final Activity mActivity; 
    private final String mTag; 
    private final Class<T> mClass; 

    /** 
    * Constructor used each time a new tab is created. 
    * 
    * @param activity 
    *   The host Activity, used to instantiate the fragment 
    * @param tag 
    *   The identifier tag for the fragment 
    * @param clz 
    *   The fragment's Class, used to instantiate the fragment 
    */ 
    public TabListener(Activity activity, String tag, Class<T> clz) { 
     mActivity = activity; 
     mTag = tag; 
     mClass = clz; 
    } 

    /* The following are each of the ActionBar.TabListener callbacks */ 

    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     // Check if the fragment is already initialized 
     if (mFragment == null) { 
      // If not, instantiate and add it to the activity 
      mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
     } else { 
      // If it exists, simply attach it in order to show it 
      ft.attach(mFragment); 
     } 
    } 

    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     if (mFragment != null) { 
      // Detach the fragment, because another one is being attached 
      ft.detach(mFragment); 
     } 
    } 

    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     // User selected the already selected tab. Usually do nothing. 
    } 
} 

而且StationsFragmentRouteFragmentDelaysFragment是相同的,只有不同的文字)

public class StationsFragment extends SherlockFragment { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.stationsfragment, container, false); 
    } 
} 

隨着對於StationsFragment佈局文件:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="Stations" /> 

</LinearLayout> 

最後清單文件:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.myapp" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="8" 
     android:targetSdkVersion="15" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".TreinVerkeer" 
      android:label="@string/app_name" 
      android:theme="@style/Theme.Sherlock.Light" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

我啓動應用程序時(所以沒有之前也馬上有同樣的問題改變方向),這通過在主要類的onCreate中刪除setContentView(R.layout.main)來解決。但是我找不到解決方案。誰能幫我這個?

+0

['FragmentTabs.java'](https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabs.java) –

回答

19

FragmentManager將自動恢復配置更改時當前顯示的任何片段(和歷史記錄)。在創建並附加新實例之前,請致電findFragmentByTag以查看目標片段的實例是否已存在。

15

感謝傑克,我已經更新了onTabSelected方法是這樣的:

public void onTabSelected(Tab tab, FragmentTransaction ft) { 
    SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); 

    // Check if the fragment is already initialized 
    if (mFragment == null && preInitializedFragment == null) { 
     // If not, instantiate and add it to the activity 
     mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); 
     ft.add(android.R.id.content, mFragment, mTag); 
    } else if (mFragment != null) { 
     // If it exists, simply attach it in order to show it 
     ft.attach(mFragment); 
    } else if (preInitializedFragment != null) { 
     ft.attach(preInitializedFragment); 
     mFragment = preInitializedFragment; 
    } 
} 

這個答案是明確的目的,學分去傑克:)

+3

仍然,你也應該擁有道具來發布這段代碼。這非常有幫助。謝謝:) – gnobal

5

還有變化Niek表示,你需要做一些微小的改變。主要只是將活動更改爲SherlockFragmentActivity。

爲了他人的利益,這裏是我的最終版本,似乎正常工作。

public static class TabListener<T extends SherlockFragment> implements ActionBar.TabListener 
    { 
     private SherlockFragment mFragment; 
     private final SherlockFragmentActivity mActivity; 
     private final String mTag; 
     private final Class<T> mClass; 

     /** Constructor used each time a new tab is created. 
     * @param activity The host Activity, used to instantiate the fragment 
     * @param tag The identifier tag for the fragment 
     * @param clz The fragment's Class, used to instantiate the fragment 
     */ 
     public TabListener(Activity activity, String tag, Class<T> clz) 
     { 
     mActivity = (SherlockFragmentActivity) activity; 
     mTag = tag; 
     mClass = clz; 
     } 


     public void onTabSelected(Tab tab, FragmentTransaction ft) 
     { 
     // Check if the fragment has already been initialised 
     SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag); 
     if (mFragment != null) 
     { 
      // If it exists, simply attach it in order to show it 
      ft.attach(mFragment); 
     } 
     else if (preInitializedFragment != null) 
     { 
      mFragment = preInitializedFragment; 
      ft.attach(mFragment); 
     } 
     else 
     { 
      // Not found, so instantiate and add it to the activity 
      mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
     } 
     } 


     public void onTabUnselected(Tab tab, FragmentTransaction ft) 
     { 
     if (mFragment != null) { 
      // Detach the fragment, because another one is being attached 
      ft.detach(mFragment); 
     } 
     } 


     public void onTabReselected(Tab tab, FragmentTransaction ft) 
     { 
     // User selected the already selected tab. Usually do nothing. 
     } 
    } 
+0

考慮到上面的情況,我有一個Sherlock Listfragment和Sherlock Fragment。你如何使標籤監聽器通用來支持列表和普通片段? –

相關問題