0

我正在开发一个应用程序,但有一件具体的事情让我感到困扰。假设我有一个活动和两个片段。FragmentA 和 FragmentB 和 FragmentA 在活动开始时附加。

我想在方向发生变化时保存片段数据和片段状态。我已经使用OnSavedInstanceState方法成功保存了片段数据。现在我想在活动中保存片段状态,以便如果发生方向变化,我想在我所在的片段上(在我的情况下,FragmentA 或 FragmentB 取决于在配置更改发生之前显示的那个)。

这就是我在Activity中保存片段状态的方式:

 @Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need into "outState"
    super.onSaveInstanceState(outState);
    outState.putLong(SS_DATE, userDate.getTime());

    android.support.v4.app.FragmentManager manager = getSupportFragmentManager();
    Fragment currentFragment = this.getSupportFragmentManager().findFragmentById(R.id.content_container);
    manager.putFragment(outState, "currentFragment", currentFragment);
}

这就是我在方向改变发生时检索我所在的片段的方式:

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

    FragmentManager manager = getSupportFragmentManager();
    @SuppressLint("CommitTransaction")
    FragmentTransaction transaction = manager.beginTransaction();

    if (savedInstanceState != null) {
        Fragment MyFragment = (Fragment) manager.getFragment(savedInstanceState, "currentFragment");

        if (MyFragment instanceof FragListStudentsAttendance) {
            Log.v("onRestore", FragListStudentsAttendance.TAG);


        }else if (MyFragment instanceof FragGetClassesForAttendance){
            Log.v("onRestore", FragGetClassesForAttendance.TAG);
            if(MyFragment!=null) {
                mFragGetClassesForAttendance = (FragGetClassesForAttendance) MyFragment;
            }else{


     mFragGetClassesForAttendance = new FragGetClassesForAttendance();
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
//            mFragGetClassesForAttendanceNew.setRetainInstance(true);
//            transaction.replace(R.id.content_ssadmin_container, mFragGetClassesForAttendanceNew, "FragGetClassesForAttendance").addToBackStack(null);
            transaction.add(R.id.content_ssadmin_container, mFragGetClassesForAttendance, FragGetClassesForAttendance.TAG);
            //transaction.replace(R.id.newEnrollmentMainContainer, mFragNewEnrollmentResults).addToBackStack("FragNewEnrollments");
            transaction.commit();
            mFragGetClassesForAttendance.setDate(userDate);
            }
        }
    }

}

现在场景 1: 如果我在片段 A 上并且我旋转设备,那么一切都可以正常工作。像片段一样具有将数据加载到列表视图中的 Web 服务,因此我检查数据是否存在,则无需运行 Web 服务并且该服务现在可以工作

场景 2: 如果我在片段 B 上并且方向发生变化,一切正常,因为它应该在片段 B 上。现在当我按下返回按钮时,片段 A 再次被调用,所有数据也来自服务。我认为这不应该发生,因为它应该在BackStack中并且它的数据被保存了。那么我现在应该在这里做什么?

场景 3:在 FragmentB 上,我注意到当我旋转设备时, FragmentA 的 saveInstanceState 函数也会被调用。为什么会这样?我在哪里用 FragmentA 替换 FragmentB ?

一些困惑:

让我也谈谈一些困惑,也许有人向我解释了尽管我已经搜索并阅读了很多关于片段和活动生命周期的内容,实际上我想保存每个活动的数据和设备旋转的片段。我知道如何使用活动(如何保存状态)来做到这一点,所以我也知道如何在片段中做到这一点(保存片段视图的状态)现在我很困惑如何告诉活动显示哪个片段以及在配置之后去哪个变化(旋转)?如果我在 FragmentB 上,FragmentA 会发生什么情况?它会在后台一次又一次地连接和分离吗?

4

1 回答 1

1

我得到了你的问题和困惑。我认为片段的生命周期让你感到困惑。它确实会让你感到困惑。

你需要学习不同的情况。1. Fragment 处于前台时的生命周期(随活动附着和分离)。请仔细观察所有将调用的方法,即 OnSaveInstance,onCreateView,OnDestroyView,onDestroy 2. Fragment 在后台的生命周期(观察上述方法) 3. Fragment 添加到后台(而不是在前台)的生命周期)

我很确定你对第 3 点感到困惑。当片段被添加到 backstack 时,它永远不会被破坏。所以旋转设备两次会将碎片数据设置为空。我认为您正在恢复 ActivityCreated 或 onViewCreated 上的数据,

我建议您在 oncreate 中恢复片段数据。当您的片段从 backstack 返回到前台时,这将为您工作。

例子

    private List<String> mCountries;</pre>
@Override
public void onCreate(Bundle savedInstanceState)
{
    if (savedInstanceState != null)
    {
        // Populate countries from bundle
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    View view = inflater.inflate(R.layout.fragment_countries, container, false);

    if (mCountries == null)
    {
        // Populate countries by calling AsyncTask
    }

    return view;
}

public void onSaveInstanceState(Bundle outState)
{
    // Save countries into bundle
}

希望这能消除您的困惑。

于 2017-01-13T11:45:12.317 回答