当前位置: 首页 > 知识库问答 >
问题:

在Android上使用下拉导航模式旋转设备时如何保留/恢复片段实例?

宗政子辰
2023-03-14

我使用的是ADT在创建使用下拉操作栏的应用程序时创建的默认代码。

问题是我无法保持片段视图状态,因为每次在下拉菜单上设置所选项目时,都会创建一个新的片段实例。

用户更改选择时就可以了。问题是当设备旋转时。我无法避免菜单被重新创建,它必须再次设置所选项目。

我只是不知道如何避免在所选项目没有改变时(如改变方向时)创建新的片段实例(并替换旧的片段实例)。

这是我的主要活动代码:

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

        setContentView(R.layout.main_activity_layout);

        // Set up the action bar to show a dropdown list.
        final ActionBar actionBar = getActionBar();
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

        // Set up the dropdown list navigation in the action bar.
        actionBar.setListNavigationCallbacks( new ArrayAdapter<String>(getActionBarThemedContextCompat(),
                android.R.layout.simple_list_item_1,
                android.R.id.text1,
                getResources().getStringArray(R.array.main_menu_array)), this);

    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Restore the previously serialized current dropdown position.
        if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
            getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        // Serialize the current dropdown position.
        outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar().getSelectedNavigationIndex());
    }

    @Override
    public boolean onNavigationItemSelected(int position, long id) {
        String[] array = getResources().getStringArray(R.array.main_menu_array);
        String name = array[position];
        if( name.equals(getString(R.string.Pontos)) ) {
            getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new MainActivityPontosFragment()).commit();
            return true;
        } else if( name.equals(getString(R.string.Sobre)) ) {
            getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new SobreFragment()).commit();
            return true;
        } else if( name.equals(getString(R.string.Temporizadores))) {
            getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new TimersListFragment()).commit();
            return true;
        }
        return false;
    }

每次创建菜单时都会调用onNavigationItemSelected,我无法避免它的娱乐。

但是,当调用onNavigationItemSelected时,如何避免创建新的片段实例?

我想不出更好的方法,但我也不知道如何做到这一点。

但我接受其他建议。

谢谢

编辑:

我将我的onNavigationItemSelected更改为this(检查最后一个如果):

        @Override
        public boolean onNavigationItemSelected(int position, long id) {
            String[] array = getResources().getStringArray(R.array.main_menu_array);
            String name = array[position];
            if( name.equals(getString(R.string.Pontos)) ) {
                getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new MainActivityPontosFragment()).commit();
                return true;
            } else if( name.equals(getString(R.string.Sobre)) ) {
                getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, new SobreFragment()).commit();
                return true;
            } else if( name.equals(getString(R.string.Temporizadores))) {
                MainActivityTimersFragment frag = (MainActivityTimersFragment) getSupportFragmentManager().findFragmentByTag(MainActivityTimersFragment.MY_TAG);
                if( frag == null ) { frag = new MainActivityTimersFragment(); }
                getSupportFragmentManager().beginTransaction().replace(R.id.mainActivityFragContainer, frag, MainActivityTimersFragment.MY_TAG).commit();
                return true;
            }
            return false;
        }

但是“frag”总是返回null。

共有2个答案

王佐
2023-03-14

尽管用户3126670很好地回答了我的问题。

我找到了它们的根源。

我一直在重建我的活动,因为我的清单只预测到活动的方向变化。我缺少需要添加到API 13的screenSize参数。

我所要做的就是:

        <activity
            android:name="br.com.mtcbrasilia.aa.MainActivity"
            android:label="@string/app_name"
            android:configChanges="locale|orientation|screenSize" <---add this
            android:launchMode="singleTop" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
        </activity>
施敏达
2023-03-14

我测试了以下使用:

     import android.support.v4.app.Fragment;

使用支持片段,并非所有内容都是我使用常规片段类时记住的,但这些是我可以根据该测试提供的答案。

在屏幕方向更改时,活动将被销毁,并调用片段的onDestroyView和onDestroy方法。

但是,当您在活动的OnCreate方法中调用super.on创建(savedInstanceState)时,片段将重新创建自己——此时片段将重新附加到您的活动。

您可以使用片段管理器通过以下方式找到这些片段:

Fragment fragment = getSupportFragmentManager().findFragmentByTag(str_ID);

另一种方法是将对片段的引用存储在静态变量中。在任何一种情况下,如果在Super. OnCreate(savedInstanceState)之前使用,manger或静态引用都将返回NULL。

fragment类中的任何非静态变量都将丢失。这是我不确定常规fragment类是否表现不同的领域之一。无论如何,您都可以重写onDestroy函数之一,并保存重新创建实例所需的所有变量/数据。

 类似资料:
  • 我试图做恢复片段视图状态值(文本视图,... 我的活动。Java语言 ProductFragment。Java语言 在ProductFragment中,我将向文本视图添加值。当我从ReportFragment开始时,视图值将在ProductFragment中清除。

  • 在需要动态添加和从viewpager中删除列表片段的应用程序中工作,当点击列表中的一个项目时,新的片段会添加到viewpager中,当需要删除swipe back片段时,这工作效果很好,但当我旋转屏幕时,页面中的片段会有两个实例,再旋转一次,实例会增加四倍。 同时,我需要持久化片段的状态(列表位置、加载的项数等),这意味着重写片段中的onsaveinstancestate并将相关数据保存在捆绑包中

  • 我搜索了很多信息,但没有一个明确的。有人能给出一个明确的解决方案和一个例子吗?

  • 我试图理解在导航选项卡中使用片段时如何保持片段视图状态。在我的努力中,我遇到了两个我找不到合适解决方案的问题。 我有两个选项卡,Tab1和Tab2。Tab1的布局由碎片A定义,Tab2的布局由碎片B定义。我遵循了这里给出的方法(编辑:自从提出这个问题以来,文档已经发生了变化)。 第一个问题:即使我的视图有ID,当片段被重新附加时(在选项卡切换旋转之后),它们的状态也不会完全恢复。特别是:具有ID的

  • 我使用底部导航视图和导航组件。请告诉我如何在切换到另一个选项卡并返回旧选项卡后不销毁片段?例如,我有三个选项卡-A、B、C。我的开始选项卡是A。导航到B后,然后返回A。当我返回选项卡A时,我不希望它被重新创建。怎么做?谢谢