双片段,动作条旋转的Andr​​oid片段、动作、oid、Andr

2023-09-12 02:25:25 作者:男人的痛你永远不会懂

我做了一个简单的机器人活动与动作条2段之间进行切换。 这一切都ok了,直到我旋转设备。在事实面前,当我转我有2片段了另一种:在previous活跃的地区之一和第一个。 为什么? 如果旋转破坏并重新创建我的活动,我为什么得到2片段?

样品code:

活动

 包rb.rfrag.namespace;

进口android.app.ActionBar;
进口android.app.ActionBar.Tab;
进口android.app.Activity;
进口android.os.Bundle;

    公共类RFragActivity延伸活动{
    / **第一次创建活动时调用。 * /
    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        //注意的setContentView()没有被使用,因为我们使用的根
        // android.R.id.content当容器为每个片段

     制表符//设置操作栏
        最后的动作条动作条= getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        //actionBar.setDisplayShowTitleEnabled(false);

        TAB键;
        标签= actionBar.newTab()
                .setText(R.string.VarsTab)
                .setTabListener(新TabListener< VarValues​​>(
                        对此,VarValues​​,VarValues​​.class));
        actionBar.addTab(标签);

        标签= actionBar.newTab()
                .setText(R.string.SecTab)
                .setTabListener(新TabListener< SecFrag>(
                        对此,SecFrag,SecFrag.class));
        actionBar.addTab(标签);
    }
}
 

TabListener

 包rb.rfrag.namespace;

进口android.app.ActionBar;
进口android.app.Activity;
进口android.app.Fragment;
进口android.app.FragmentManager;
进口android.app.FragmentTransaction;
进口android.app.ActionBar.Tab;

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

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

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

    公共无效onTabSelected(TAB键,FragmentTransaction英尺){
        //检查片段已初始化
        如果(mFragment == NULL){
            //如果没有,实例化并把它添加到活动
            mFragment = Fragment.instantiate(mActivity,mClass.getName());
            ft.add(android.R.id.content,mFragment,MTAG);
        } 其他 {
            //如果它存在,只需将它为了显示它
            ft.attach(mFragment);
        }
    }

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

解决方案

我用决心的onSaveInstanceState onRestoreInstanceState 在活动,以保持选定的选项卡并修改 onTabSelected 如下:

最后修改避免了Android的重建片段不destoy。不过,我不明白为什么活动是由旋转事件被销毁,而当前片段没有。 (你有没有关于这方面的一些想法?)

 公共无效onTabSelected(TAB键,FragmentTransaction英尺){
        // previous片段管理
        片段prevFragment;
        FragmentManager FM = mActivity.getFragmentManager();
        prevFragment = fm.findFragmentByTag(MTAG);
        如果(prevFragment!= NULL){
            mFragment = prevFragment;
        } // \ previous片段管理

        //检查片段已初始化
        如果(mFragment == NULL){
            //如果没有,实例化并把它添加到活动
            mFragment = Fragment.instantiate(mActivity,mClass.getName());
            ft.add(android.R.id.content,mFragment,MTAG);
        } 其他 {
            //如果它存在,只需将它为了显示它
            ft.attach(mFragment);
        }
    }
 

I've made a simple Android Activity with an ActionBar to switch between 2 fragments. It's all ok until I rotate the device. In facts, when I rotate I've got 2 fragment one over the other: the previous active one and the first one. Why? If the rotation destroy and recreate my activity, why I obtain 2 fragments?

Sample code:

Activity

package rb.rfrag.namespace;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.os.Bundle;

    public class RFragActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Notice that setContentView() is not used, because we use the root
        // android.R.id.content as the container for each fragment

     // setup action bar for tabs
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        //actionBar.setDisplayShowTitleEnabled(false);

        Tab tab;
        tab = actionBar.newTab()
                .setText(R.string.VarsTab)
                .setTabListener(new TabListener<VarValues>(
                        this, "VarValues", VarValues.class));
        actionBar.addTab(tab);

        tab = actionBar.newTab()
                .setText(R.string.SecTab)
                .setTabListener(new TabListener<SecFrag>(
                        this, "SecFrag", SecFrag.class));
        actionBar.addTab(tab);
    }
}

TabListener

package rb.rfrag.namespace;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ActionBar.Tab;

public class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment 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 = Fragment.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);
        }
    }
}

解决方案

I've resolved using onSaveInstanceState and onRestoreInstanceState in the Activity to maintain the selected tab and modifying onTabSelected as follows.

The last modify avoids that Android rebuild the Fragment it doesn't destoy. However I don't understand why the Activity is destroyed by the rotation event while the current Fragment no. (Have you some idea about this?)

public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // previous Fragment management
        Fragment prevFragment;
        FragmentManager fm = mActivity.getFragmentManager();
        prevFragment = fm.findFragmentByTag(mTag); 
        if (prevFragment != null) { 
            mFragment = prevFragment; 
        } // \previous Fragment management

        // Check if the fragment is already initialized
        if (mFragment == null) {
            // If not, instantiate and add it to the activity
            mFragment = Fragment.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);
        }
    }