在轮换中创建新片段和从管理器获取现有片段之间的区别

时间:2018-05-02 09:40:27

标签: android android-fragments

看来我是否将retainInstance设置为true,当我旋转设备时,我得到一个现有的片段。不同的是,如果我将其设置为true,我会得到" test = yes!"否则我会得到" test = no!"单击测试按钮后旋转设备后更改test。也就是说,如果我保留实例,则保留成员变量。

但正如我所说,即使我不保留它,我也会从经理那里得到一个现有的片段(总是得到"重复使用现有的"轮换)。在这种情况下,如果所有成员变量都丢失并且重新创建了片段的视图,那么保留了什么?获取片段的现有实例有什么意义?

在活动的onCreate中,

    var frag = supportFragmentManager.findFragmentById(R.id.frame)

    if(frag == null)
    {
        frag = Fragment1.newInstance("", "");
    }
    else
    {
        Log.d("sss", "Reusing exsiting");
    }

    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.frame, frag)
    transaction.commit()

在片段中,

var test = "no!";

override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
    super.onViewCreated(view, savedInstanceState)
    Log.d("sss", "test = " + test);
    testButton.setOnClickListener {
        test = "yes!";
    }
}

2 个答案:

答案 0 :(得分:2)

我花了几个小时试图用不同的场景重新创建你的情况。首先,我应该指出片段的生命周期实际上是如此复杂,以至于在Google I / O 2018期间,其中一位主要开发人员向观众询问onCreate()的{​​{1}}方法是否为Activity首先调用或Fragment的调用。答案是,它取决于SDK版本。但他们越来越关注兼容性库,并建议开发人员使用它们在不同的设备上获得通用体验,以及享受处理Fragments的新API,这对我们来说更容易。

在查看AppCompatActivity类的文档时,我意识到这种行为是处理片段的方式。

Protected methods
void    onCreate(Bundle savedInstanceState)
Perform initialization of all fragments.

void    onDestroy()
Destroy all fragments.

void    onPostCreate(Bundle savedInstanceState)
void    onPostResume()
Dispatch onResume() to fragments.

void    onSaveInstanceState(Bundle outState)
Save all appropriate fragment state.

void    onStart()
Dispatch onStart() to all fragments.

void    onStop()
Dispatch onStop() to all fragments.

正如您所看到的,他们"保存所有适当的片段状态"在onSaveInstanceState();这意味着在Activity被销毁并重新创建之后,状态将在稍后恢复。因此,在onDestroy()中,所有片段都会被破坏,并且当再次创建Activity时,它们也会被重新创建。为确保您可以在FragmentActivity中覆盖这些方法并检查结果。如果您没有检查FragmentManager已经附加的片段,onCreate()的{​​{1}}方法将被调用两次,一次直接由您添加 - 添加为新Fragment - 并且由Fragment本身。

关于AppCompatActivity,文档说它会在配置更改期间保留成员变量,并会导致retainInstance = true的生命周期略有不同。

答案 1 :(得分:1)

<强> setRetainInstance(真)

控制是否在活动重新创建(例如从配置更改)中保留片段实例。这只能用于不在后栈中的片段。如果设置,则重新创建活动时片段生命周期将略有不同:

onDestroy()将不会被调用(但 onDetach()仍将是,因为该片段正在与其当前活动分离。)

由于未重新创建片段,因此不会调用

onCreate(Bundle)

仍然会调用

onAttach(活动) onActivityCreated(Bundle)