2012-05-08 101 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。你如何使标签监听器通用来支持列表和普通片段? –

相关问题