在标签交换片段片段、标签

2023-09-12 07:08:55 作者:盖世小仙女

我要创建一个使用ActionBarSherlock的应用程序。该应用程序由三个选项卡,并在他们每个人,多屏幕基于用户输入的连续显示。我能够标签之间切换片段,但片段的切换的在的标签给出了一个问题。我已经尝试过这样的:

在主类:

  SingleStationFragment singleStationFragment =新SingleStationFragment();
FragmentTransaction交易= getSupportFragmentManager()的BeginTransaction()。
transaction.replace(android.R.id.content,singleStationFragment);
transaction.addToBackStack(空);
器transaction.commit();
 

本的确实的替换第一个片段第二,但是当我更改选项卡,第二个片段仍清晰可见,呈现出新的选项卡上的旧标签的内容之上的内容。我想,不知何故,我需要分离的 onTabUnselected 第二个片段,但我不知道怎么去引用这个片段。

谁能帮助我?

为了清楚起见,一些显著类:

我的主类:

 公共类TreinVerkeer扩展SherlockFragmentActivity {

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        setupTabs(savedInstanceState);

    }

    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
        MenuInflater充气= getSupportMenuInflater();
        inflater.inflate(R.menu.menu,菜单);
        返回true;
    }

    私人无效setupTabs(包savedInstanceState){
        动作条动作条= getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        。TAB键= actionBar.newTab()的setText(站)setTabListener(新TabListener< StationsFragment>(这一点,站,StationsFragment.class));
        actionBar.addTab(标签);

        。标签= actionBar.newTab()的setText(ROUTE)setTabListener(新TabListener< RouteFragment>(这一点,路线,RouteFragment.class));
        actionBar.addTab(标签);

        。标签= actionBar.newTab()的setText(延误)setTabListener(新TabListener< D​​elaysFragment>(这一点,延迟,DelaysFragment.class));
        actionBar.addTab(标签);

        如果(savedInstanceState!= NULL){
            actionBar.setSelectedNavigationItem(savedInstanceState.getInt(标签,0));
        }
    }

    @覆盖
    保护无效的onSaveInstanceState(包outState){
        super.onSaveInstanceState(outState);
        outState.putInt(标签,getSupportActionBar()getSelectedNavigationIndex());
    }
}
 
多协议标签交换

在Android开发者网站的TabListener(从添加导航标签,提供一些小的改动):

 公共类TabListener<吨延伸SherlockFragment>实现com.actionbarsherlock.app.ActionBar.TabListener {
    私人SherlockFragment mFragment;
    私人最终活动mActivity;
    私人最终字符串MTAG;
    私人最终类别< T> mClass;

    / **
     *构造函数用于创建一个新的标签,每次。
     *
     * @参数活动
     *主机活动,用实例片段
     * @参数标签
     *标识符标记的片段
     * @参数CLZ
     *片段的类,用于实例片段
     * /
    公共TabListener(活动活动,字符串变量,类< T> CLZ){
        mActivity =活动;
        MTAG =标签;
        mClass = CLZ;
    }

    / *下面是每个ActionBar.TabListener回调* /

    公共无效onTabSelected(TAB键,FragmentTransaction英尺){
    SherlockFragment preInitializedFragment =(SherlockFragment)mActivity.getSupportFragmentManager()findFragmentByTag(MTAG)。

    //检查片段已初始化
    如果(mFragment == NULL和放大器;&安培; preInitializedFragment == NULL){
        //如果没有,实例化并把它添加到活动
        mFragment =(SherlockFragment)SherlockFragment.instantiate(mActivity,mClass.getName());
        ft.add(android.R.id.content,mFragment,MTAG);
    }否则,如果(mFragment!= NULL){
        //如果它存在,只需将它为了显示它
        ft.attach(mFragment);
    }否则,如果(preInitializedFragment!= NULL){
        ft.attach(preInitializedFragment);
        mFragment = preInitializedFragment;
    }
}

    公共无效onTabUnselected(TAB键,FragmentTransaction英尺){
        如果(mFragment!= NULL){
            //分离的片段,因为另一个被连接
            ft.detach(mFragment);
        }
    }

    公共无效onTabReselected(TAB键,FragmentTransaction英尺){
        //用户选择已经选择的选项卡。通常什么也不做。
    }
}
 

StationsFragment (RouteFragment 和 DelaysFragment 是同样的,只有不同的文本)

 公共类StationsFragment扩展SherlockFragment {

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
    }

    @覆盖
    公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){
        返回inflater.inflate(R.layout.stationsfragment,集装箱,假);
    }
}
 

解决方案

那么,什么情况是,在 TabListener ,在 onTabUnselected 法,片段完全没有剥离,导致它仍然是节目的同时,一个新的片段是如图所示。

的事业,这是,是,片段被分离是第一个片段,而不是我的第二个片段。我做了一些修改。

活动

  SingleStationFragment singleStationFragment =新SingleStationFragment();
FragmentTransaction交易= getSupportFragmentManager()的BeginTransaction()。
transaction.replace(android.R.id.content,singleStationFragment,站);
transaction.addToBackStack(空);
器transaction.commit();
 

在这里,我已经添加了标记中的替换()的方法,这是相同的标签作为第一个片段。 该 TabListener 如下内容:

 公共类TabListener<吨延伸SherlockFragment>实现com.actionbarsherlock.app.ActionBar.TabListener {
    私人最终SherlockFragmentActivity mActivity;
    私人最终字符串MTAG;
    私人最终类别< T> mClass;

    私人SherlockFragment mFragment;

    公共TabListener(SherlockFragmentActivity活动,字符串变量,类< T> CLZ){
        mActivity =活动;
        MTAG =标签;
        mClass = CLZ;
    }

    公共无效onTabSelected(TAB键,FragmentTransaction英尺){
        SherlockFragment preInitializedFragment =(SherlockFragment)mActivity.getSupportFragmentManager()findFragmentByTag(MTAG)。
        如果(preInitializedFragment == NULL){
            mFragment =(SherlockFragment)SherlockFragment.instantiate(mActivity,mClass.getName());
            ft.add(R.id.treinverkeer_fragmentcontent,mFragment,MTAG);
        } 其他 {
            ft.attach(preInitializedFragment);
        }
    }

    公共无效onTabUnselected(TAB键,FragmentTransaction英尺){
        SherlockFragment preInitializedFragment =(SherlockFragment)mActivity.getSupportFragmentManager()findFragmentByTag(MTAG)。

        如果(preInitializedFragment!= NULL){
            ft.detach(preInitializedFragment);
        }否则,如果(mFragment!= NULL){
            ft.detach(mFragment);
        }
    }

    公共无效onTabReselected(TAB键,FragmentTransaction英尺){
        //用户选择已经选择的选项卡。通常什么也不做。
    }
}
 

onTabUnselected 方法,我现在首先检索正确的片段,然后卸下。

希望这可以帮助别人!

I'm creating an app that uses ActionBarSherlock. The app consists of three tabs, and in each of them, multiple screens are shown consecutively based on user input. I am able to switch Fragments between tabs, but the switching of fragments within tabs gives a problem. I've tried it like this:

In the main class:

SingleStationFragment singleStationFragment = new SingleStationFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, singleStationFragment);
transaction.addToBackStack(null);
transaction.commit();

This does replace the first fragment for the second, but when I change tabs, the second fragment is still visible, showing the content of the new tab on top of the content of the old tab. I think somehow I need to detach the second fragment in onTabUnselected, but I have no idea how to get a reference to this Fragment.

Can anyone help me with this?

For clarity, some significant classes:

My main class:

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());
    }
}

The TabListener (from "Adding Navigations Tabs" on the Android developer site with some minor changes):

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) {
    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;
    }
}

    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.
    }
}

And StationsFragment (RouteFragment and DelaysFragment are the same, with only different text)

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);
    }
}

解决方案

So what happened was that, in TabListener, in the onTabUnselected method, the Fragment was not detached, causing it to still be show while a new Fragment was shown.

The cause to this was, that the Fragment that was detached was the first fragment, and not my second fragment. I've made some changes.

In the Activity:

SingleStationFragment singleStationFragment = new SingleStationFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(android.R.id.content, singleStationFragment, "STATIONS");
transaction.addToBackStack(null);
transaction.commit();

Here I've added the "STATIONS" tag in the replace() method, which is the same tag as the first fragment. The TabListener is now as follows:

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

    private SherlockFragment mFragment;

    public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        SherlockFragment preInitializedFragment = (SherlockFragment) mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
        if (preInitializedFragment == null) {
            mFragment = (SherlockFragment) SherlockFragment.instantiate(mActivity, mClass.getName());
            ft.add(R.id.treinverkeer_fragmentcontent, mFragment, mTag);
        } else {
            ft.attach(preInitializedFragment);
        }
    }

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

        if (preInitializedFragment != null) {
            ft.detach(preInitializedFragment);
        } else if (mFragment != null) {
            ft.detach(mFragment);
        }
    }

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

In the onTabUnselected method I now first retrieve the correct Fragment, then detach it.

Hope this helps someone!