生成的绑定 class 仅将 LayoutInflater 作为其唯一参数
Generated binding class that only takes a LayoutInflater as its sole argument
来自 Android 数据绑定库的 generated binding class 有不同版本的 inflate
方法:一个看起来像通常的 LayoutInflater.inflate
方法,它采用 viewGroup
和 attachToRoot
参数,还有一个只接受 LayoutInflater
而没有其他参数。
文档没有解释两者之间的区别,不幸的是 Android Studio 不允许我逐步查看 inflate
的源代码,这样我才能弄清楚它是哪些值在内部使用 viewGroup
和 attachToRoot
。在屏幕上放置片段时,我注意到两者之间没有区别。当我将它用于 RecyclerView 项目时,仅采用 LayoutInflater
的 inflate
方法无法正确放置项目。
所以我的问题是:此方法在内部使用的 viewGroup
和 attachToRoot
的值是什么?在片段的 onCreateView
中使用它是否合适?
如果您使用的是 Kotlin,仅当 layoutId
事先未知时才使用此版本:
private lateinit var viewModel: MyViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding : MyFragmentBinding = DataBindingUtil.inflate(inflater, R.layout.my_fragment, container, false)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
binding.myViewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}
否则使用生成的Binding
class膨胀方法:
lateinit var binding: MyFragmentBinding
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = MyFragmentBinding.inflate(inflater, container, false)
return binding.root
}
更新:
So my question is: What values for viewGroup and attachToRoot does
this method use internally and is it appropriate to use it in a
fragment's onCreateView?
当您调用 inflate
时仅使用 inflater
作为参数,null
和 false
是传递的默认值
IE。当你这样做时:
val binding: MyFragmentBinding = MyFragmentBinding.inflate(inflater)
这类似于做:
val binding: MyFragmentBinding = MyFragmentBinding.inflate(inflater, null, false)
What values for viewGroup and attachToRoot does this method use internally?
这些参数反映了 LayoutInflater
上的参数,其中 root: ViewGroup
被描述为
Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.) This value may be null
.
来源:LayoutInflater docs,强调我的。
root
参数用于 generate LayoutParams
来自 layout_*
XML 属性的膨胀视图。每个布局可以理解一组不同的布局属性并定义一组不同的默认值。这就是为什么你应该总是通过 root
。唯一不可能的地方是在展开对话框视图时。
绑定上的单参数方法不提供 root
布局,因此此时不会为膨胀视图生成 LayoutParams
。换句话说,inflate(inflater) == inflate(inflater, null, false)
.
如果视图没有 LayoutParams
当您附加它时,它的新父布局将使用 generateDefaultLayoutParams
.[=51= 生成默认值]
如果您遵循 generateDefaultLayoutParams
在 RecyclerView
中的操作,it's delegated to the layout manager. Now look at the default LayoutParams
provided by LinearLayoutManager
:
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
通常,如果您打算有一个垂直列表,您会在项目上设置 android:layout_width="match_parent"
。但是,当您将没有 LayoutParams
的视图附加到 RecyclerView
时,它会将两个维度都设置为 wrap_content
。这就是为什么你的布局在用 root == null
.
膨胀时看起来不对的原因
Is it appropriate to use [the one-parameter inflate
method] in a fragment's onCreateView
?
单参数膨胀器可以用于膨胀对话框视图,其中没有 parent/container/root 视图。
通常,您会将片段附加到 FrameLayout
或 FragmentContainerView
(扩展 FrameLayout
)。 FrameLayout
生成 LayoutParams
,宽度和高度为 match_parent
。如果这对您的片段没问题,您可以在绑定上使用单参数 inflate
方法。
否则始终使用 provided/known 父代生成正确的 LaoyutParams
。不要依赖您要附加视图的容器提供的默认 LayoutParams
,即使它是相同的布局。您在 XML 中定义了一些布局参数,您希望它们得到尊重。
请记住,如果您持有对绑定的引用,则会涉及一些片段生命周期仪式。
这是我当前的片段 + 视图绑定设置:
// Nullable reference so we can use it later and clear it later.
private var binding: ExampleFragmentBinding? = null
private fun requireBinding() = checkNotNull(binding)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
// Respect the XML layout params.
val binding = ExampleFragmentBinding.inflate(inflater, container, false)
this.binding = binding
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = requireBinding()
// Do stuff with the views.
}
override fun onDestroyView() {
// Detach view hierarchy reference from fragment, which may prevent memory leaks.
this.binding = null
super.onDestroyView()
}
来自 Android 数据绑定库的 generated binding class 有不同版本的 inflate
方法:一个看起来像通常的 LayoutInflater.inflate
方法,它采用 viewGroup
和 attachToRoot
参数,还有一个只接受 LayoutInflater
而没有其他参数。
文档没有解释两者之间的区别,不幸的是 Android Studio 不允许我逐步查看 inflate
的源代码,这样我才能弄清楚它是哪些值在内部使用 viewGroup
和 attachToRoot
。在屏幕上放置片段时,我注意到两者之间没有区别。当我将它用于 RecyclerView 项目时,仅采用 LayoutInflater
的 inflate
方法无法正确放置项目。
所以我的问题是:此方法在内部使用的 viewGroup
和 attachToRoot
的值是什么?在片段的 onCreateView
中使用它是否合适?
如果您使用的是 Kotlin,仅当 layoutId
事先未知时才使用此版本:
private lateinit var viewModel: MyViewModel
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding : MyFragmentBinding = DataBindingUtil.inflate(inflater, R.layout.my_fragment, container, false)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
binding.myViewModel = viewModel
binding.lifecycleOwner = this
return binding.root
}
否则使用生成的Binding
class膨胀方法:
lateinit var binding: MyFragmentBinding
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val binding = MyFragmentBinding.inflate(inflater, container, false)
return binding.root
}
更新:
So my question is: What values for viewGroup and attachToRoot does this method use internally and is it appropriate to use it in a fragment's onCreateView?
当您调用 inflate
时仅使用 inflater
作为参数,null
和 false
是传递的默认值
IE。当你这样做时:
val binding: MyFragmentBinding = MyFragmentBinding.inflate(inflater)
这类似于做:
val binding: MyFragmentBinding = MyFragmentBinding.inflate(inflater, null, false)
What values for viewGroup and attachToRoot does this method use internally?
这些参数反映了 LayoutInflater
上的参数,其中 root: ViewGroup
被描述为
Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.) This value may be
null
.
来源:LayoutInflater docs,强调我的。
root
参数用于 generate LayoutParams
来自 layout_*
XML 属性的膨胀视图。每个布局可以理解一组不同的布局属性并定义一组不同的默认值。这就是为什么你应该总是通过 root
。唯一不可能的地方是在展开对话框视图时。
绑定上的单参数方法不提供 root
布局,因此此时不会为膨胀视图生成 LayoutParams
。换句话说,inflate(inflater) == inflate(inflater, null, false)
.
如果视图没有 LayoutParams
当您附加它时,它的新父布局将使用 generateDefaultLayoutParams
.[=51= 生成默认值]
如果您遵循 generateDefaultLayoutParams
在 RecyclerView
中的操作,it's delegated to the layout manager. Now look at the default LayoutParams
provided by LinearLayoutManager
:
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
通常,如果您打算有一个垂直列表,您会在项目上设置 android:layout_width="match_parent"
。但是,当您将没有 LayoutParams
的视图附加到 RecyclerView
时,它会将两个维度都设置为 wrap_content
。这就是为什么你的布局在用 root == null
.
Is it appropriate to use [the one-parameter
inflate
method] in a fragment'sonCreateView
?
单参数膨胀器可以用于膨胀对话框视图,其中没有 parent/container/root 视图。
通常,您会将片段附加到 FrameLayout
或 FragmentContainerView
(扩展 FrameLayout
)。 FrameLayout
生成 LayoutParams
,宽度和高度为 match_parent
。如果这对您的片段没问题,您可以在绑定上使用单参数 inflate
方法。
否则始终使用 provided/known 父代生成正确的 LaoyutParams
。不要依赖您要附加视图的容器提供的默认 LayoutParams
,即使它是相同的布局。您在 XML 中定义了一些布局参数,您希望它们得到尊重。
请记住,如果您持有对绑定的引用,则会涉及一些片段生命周期仪式。
这是我当前的片段 + 视图绑定设置:
// Nullable reference so we can use it later and clear it later.
private var binding: ExampleFragmentBinding? = null
private fun requireBinding() = checkNotNull(binding)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
// Respect the XML layout params.
val binding = ExampleFragmentBinding.inflate(inflater, container, false)
this.binding = binding
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val binding = requireBinding()
// Do stuff with the views.
}
override fun onDestroyView() {
// Detach view hierarchy reference from fragment, which may prevent memory leaks.
this.binding = null
super.onDestroyView()
}