【问题标题】:Tab content stays visible after changing tab after orientation change方向更改后更改选项卡后选项卡内容保持可见
【发布时间】:2012-05-08 07:15:13
【问题描述】:

我正在使用ActionBarSherlock 在我的应用程序中实现带有标签的ActionBar。 当我启动应用程序并从选项卡切换到选项卡时,一切都很好。但是,当我从纵向模式更改为横向模式时,上次活动的选项卡的内容仍然可见。更改为另一个选项卡会导致在旧内容之上绘制新内容(见图)。

我的主要课程:

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>

最后是 Manifest 文件:

<?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) 解决了这个问题。但是,我找不到解决方案。谁能帮我解决这个问题?

【问题讨论】:

标签: android tabs actionbarsherlock


【解决方案1】:

FragmentManager 将在配置更改时自动恢复当前显示的任何片段(和历史记录)。在创建和附加新实例之前调用findFragmentByTag 以查看目标片段的实例是否已存在。

【讨论】:

    【解决方案2】:

    感谢 Jake,我更新了 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;
        }
    }
    

    此答案仅用于澄清目的,感谢 Jake :)

    【讨论】:

    • 不过,您也应该得到支持来发布此代码。这很有帮助。谢谢:)
    【解决方案3】:

    除了 Niek 发布的更改之外,您还需要进行一些微不足道的更改。主要是把Activity改成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.
          }
       }
    

    【讨论】:

    • 考虑到与上面相同的情况,我有一个 Sherlock Listfragment 和 Sherlock Fragment。您如何使选项卡侦听器通用以支持列表和普通片段?
    猜你喜欢
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 2021-12-05
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多