Android 导航组件生命周期

Android 导航组件生命周期,android,android-fragments,android-jetpack,android-architecture-navigation,Android,Android Fragments,Android Jetpack,Android Architecture Navigation,我已经试用导航组件一段时间了,但不知怎么的,我并没有找到导航组件当前生命周期背后的原因(或解释)。以下是一些需要澄清的问题 1.碎片间流动 在导航组件中,每次访问(或重新访问)时都会重新创建每个片段(或者说页面)。因此,当您在A并转到B时,A将被销毁,稍后当您返回A时(如按下后退按钮)A将从拉伸创建 在传统的活动模式中,当您返回到a时,它只会转到onResume,因为它在移动到B时没有被破坏。导航组件中更改此模式的任何原因 重新创建的问题是当你有很多数据,需要时间重新绘制,感觉应用程序冻结了。一

我已经试用导航组件一段时间了,但不知怎么的,我并没有找到导航组件当前生命周期背后的原因(或解释)。以下是一些需要澄清的问题

1.碎片间流动 在导航组件中,每次访问(或重新访问)时都会重新创建每个片段(或者说页面)。因此,当您在
A
并转到
B
时,
A
将被销毁,稍后当您返回
A
时(如按下后退按钮)
A
将从拉伸创建

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

重新创建的问题是当你有很多数据,需要时间重新绘制,感觉应用程序冻结了。一个例子就是简单的主页(比如Facebook新闻提要)。保存数据可以使用
ViewModel
处理,但再次绘制所有提要需要时间,并且会冻结

娱乐还产生了另一个问题。假设此场景:
A
有一个
正在折叠的AppBar
和一个
嵌套的ScrollView
。用户向下滚动,
AppBar
将折叠,然后用户移动到另一个页面
B
。当他返回到
A
时,它将被重新绘制,
AppBar
将被展开。我不确定这是一个bug还是我应该做些什么来修复它?因此,这里的任何解决方案都是受欢迎的

2.活动娱乐
若由于某些原因(如方向更改)重新创建活动,则导航组件中的每个页面都将重新创建,直到当前目标。虽然调用了
onCreate
Fragment not
onCreateView
方法,但我认为在活动中创建片段没有意义。欢迎任何解释。

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

然而,如果您担心的是重新膨胀布局并重新获取片段的数据,那么可以通过以下两种方法轻松解决

创建视图后,将其存储在变量中,并在调用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

 }
资料来源:


将ViewModel与片段一起使用,并将所需数据作为成员变量保存。这样,在替换关联片段时,数据不会被清除。ViewModel仅在片段的onDestroy()上被清除,这只有在销毁父活动时才会发生

当迁移到应用程序时,我们使用片段来连接数据和视图的方式发生了轻微的变化,而且变化很好。它迫使我们区分
片段
视图
生命周期

导航前:使用
Fragment
lifecycleScope
onCreate()
中观察
LiveData

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
    }
  }
}
主要注意事项:

  • 并非所有生命周期所有者都是相同的。重新创建视图时(使用导航库和向上/向后导航时),片段生命周期将不会执行观察者
  • 在创建视图之前,无法访问
    viewLifecycleOwner

  • 希望这有助于防止开发人员迁移到导航时替换
    LiveData
    代码。

    您的
    nav_图可能有问题。始终存在
    片段backstack
    。即使在Nav组件中,我实际上也没有在我的
    Nav_图
    后堆栈上添加任何额外的内容,但我的意思是,它进入后堆栈片段的
    onCreateView
    ,并被重新绘制,但这将在替换后每按一次后重置
    视图
    变量。还有其他解决办法吗?
    ...
    
    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
        }
      }
    }