使用 requireView() 初始化视图绑定

Initializing view binding with requireView()

最近我开始喜欢使用 requireView() 懒惰地初始化我的视图绑定。

详细来说,我倾向于这样写:

class ExampleFragment : Fragment() {
    
    private val binding by lazy { FragmentExampleBinding.bind(requireView()) }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // make use of binding
    }

}

... 而不是这个:

class ExampleFragment : Fragment() {
    
    private lateinint var binding: FragmentExampleBinding
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        binding = FragmentExampleBinding.bind(view)

        // make use of binding
    }

}

我感觉更简洁了(虽然只是省了一两行)。但是,我还没有看到它在任何地方使用过,这就提出了实际问题: 这种方法有什么问题吗?有什么我忽略的吗?

注意:我第一次在ie中看到使用binding。协程可能导致 requireView() 在片段被杀死后被调用(因此抛出 IllegalStateException)。不过,这对我来说似乎并不太重要,因为该片段的所有协程都应在其 viewLifecycleOwner“之下”被称为,因此不应比它长寿。

从技术上讲,当 Fragment 的视图被销毁时,您的两个示例都会泄露您的视图。如果您不关心这一点,除了 属性 委托和 Lazy 的默认 thread-safety 模式的一些微不足道的开销之外,您的版本并不比使用 lateinit 差。

Some argue (see onDestroyView section) that it doesn't matter if you leak views from a Fragment, because the Fragment instance lives in a destroyed state only temporarily. For more information, see .

实际上,无论如何我都不需要在 onViewCreated 之外使用绑定,所以我只使用局部变量而不是 属性。