导航组件生命周期

时间:2019-06-25 07:41:22

标签: android android-fragments android-jetpack android-architecture-navigation

我已经尝试了一段时间的导航组件,但是以某种方式没有得到当前导航组件生命周期背后的原因(或解释)。这里有一些需要澄清的地方。

1。片段到片段流

在导航组件中,每次访问(或重新访问)时都会重新创建每个片段(或说页面)。因此,当您在A处并转到B时,A被销毁,随后当您返回到A时(如按返回按钮)A从拉伸创建。

在传统的活动模式中,当您返回到A时,它只会转到onResume,因为它移到B时并没有被破坏。导航组件中是否更改了此模式的任何原因?

重新创建的问题是,当您有大量数据并且需要重绘时间时,感觉就像应用程序冻结了一样。一个简单的主页就是一个例子(例如Facebook NewsFeed)。可以使用ViewModel处理保留数据,但是再次绘制所有提要需要时间,并且将冻结。

娱乐产生了另一个问题。假定这种情况:A的{​​{1}}和Collapsing AppBar。用户向下滚动,NestedScrollView将折叠,然后用户移至另一个页面AppBar。当他回到B时,它将重新绘制,并展开A。我不确定这是一个错误还是应该做些修复?因此,这里也欢迎任何解决方案。

2。活动娱乐

如果由于某些原因(例如方向改变)而重新创建活动,则会重新创建导航组件中的每个页面,直到当前目标为止。尽管调用了不是AppBar的Fragment的onCreate方法,但我看不出在Activity娱乐中创建Fragments的意义。任何解释都将受到欢迎。

2 个答案:

答案 0 :(得分:2)

导航组件目前仅支持片段替换。因此,您将无法像手动片段事务那样添加()片段。

但是,如果您担心要重新扩大布局并重新获取片段的数据,则可以通过以下两种方法轻松解决。

创建视图后,将其存储在变量中,并在调用onCreateView()时使用它。

private var view: View? = null

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    if (view == null) {
        view = inflater.inflate(R.layout.fragment_list, container, false)
                //...
    }

    return view

 }

来源:https://twitter.com/ianhlake/status/1103522856535638016

将ViewModel与Fragment一起使用,并将所需的数据作为成员变量保存。这样,替换关联的片段时不会清除数据。仅在片段的onDestroy()上清除ViewModel,这仅在销毁父活动时才会发生。 https://developer.android.com/images/topic/libraries/architecture/viewmodel-lifecycle.png

答案 1 :(得分:1)

在迁移到Navigation library时,我们使用片段桥接数据和视图的方式发生了微小的变化,并且变化很好。它迫使我们区分FragmentView生命周期。

预导航:使用LiveData的{​​{1}}观察onCreate()中的Fragment

lifecycleScope

导航:使用import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels ... import kotlinx.android.synthetic.main.old_fragment.* class OldFragment : Fragment(R.layout.old_fragment) { private val vm by activityViewModels<MainViewModel>() override fun onCreate(savedInstanceState: Bundle?) { vm.getLiveData().observe(this) { data -> oldTextView.text = data.name } } } 范围观察LiveData中的onViewCreated()

viewLifecycleOwner

主要注意事项:

  1. 并非所有生命周期所有者都是相同的。重新创建视图时(使用导航库并向上/向后导航时),片段生命周期将不会执行观察器。
  2. 创建视图之前,无法访问... class NewFragment : Fragment() { private val vm by activityViewModels<MainViewModel>() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { vm.getLiveData().observe(viewLifecycleOwner) { data -> oldTextView.text = data.name } } }

希望这可以防止开发人员迁移到导航时替换viewLifecycleOwner代码。