我可以在 Android Studio 中为选项菜单使用数据绑定吗?
Can I use Databinding for Options menu in Android Studio?
以下代码来自项目architecture-samples,大家可以看看here.
我知道我可以使用 viewDataBinding.viewmodel
来访问布局控件或数据。
但是在下面的代码中,我发现出现了val view = activity?.findViewById<View>(R.id.menu_filter) ?: return
,这是一个传统的代码。
有没有办法使用Databinding
或Viewbinding
技术访问选项菜单?
class TasksFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewDataBinding = TasksFragBinding.inflate(inflater, container, false).apply {
viewmodel = viewModel
}
setHasOptionsMenu(true)
return viewDataBinding.root
}
override fun onOptionsItemSelected(item: MenuItem) =
when (item.itemId) {
R.id.menu_clear -> {
viewModel.clearCompletedTasks()
true
}
R.id.menu_filter -> {
showFilteringPopUpMenu()
true
}
R.id.menu_refresh -> {
viewModel.loadTasks(true)
true
}
else -> false
}
private fun showFilteringPopUpMenu() {
val view = activity?.findViewById<View>(R.id.menu_filter) ?: return
PopupMenu(requireContext(), view).run {
menuInflater.inflate(R.menu.filter_tasks, menu)
setOnMenuItemClickListener {
viewModel.setFiltering(
when (it.itemId) {
R.id.active -> TasksFilterType.ACTIVE_TASKS
R.id.completed -> TasksFilterType.COMPLETED_TASKS
else -> TasksFilterType.ALL_TASKS
}
)
true
}
show()
}
}
...
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<import type="androidx.core.content.ContextCompat" />
<variable
name="viewmodel"
type="com.example.android.architecture.blueprints.todoapp.tasks.TasksViewModel" />
</data>
...
</layout>
如 docs 中所述:
View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
In most cases, view binding replaces findViewById
.
看看粗体字,您会注意到视图绑定仅适用于 XML 布局(位于 res/layout
),而菜单位于 res/menu
.
此外,视图绑定使用 findViewById
,而菜单使用 menu.findItem(R.id.menu_id)
,因此这是不可能的。
以下代码来自项目architecture-samples,大家可以看看here.
我知道我可以使用 viewDataBinding.viewmodel
来访问布局控件或数据。
但是在下面的代码中,我发现出现了val view = activity?.findViewById<View>(R.id.menu_filter) ?: return
,这是一个传统的代码。
有没有办法使用Databinding
或Viewbinding
技术访问选项菜单?
class TasksFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
viewDataBinding = TasksFragBinding.inflate(inflater, container, false).apply {
viewmodel = viewModel
}
setHasOptionsMenu(true)
return viewDataBinding.root
}
override fun onOptionsItemSelected(item: MenuItem) =
when (item.itemId) {
R.id.menu_clear -> {
viewModel.clearCompletedTasks()
true
}
R.id.menu_filter -> {
showFilteringPopUpMenu()
true
}
R.id.menu_refresh -> {
viewModel.loadTasks(true)
true
}
else -> false
}
private fun showFilteringPopUpMenu() {
val view = activity?.findViewById<View>(R.id.menu_filter) ?: return
PopupMenu(requireContext(), view).run {
menuInflater.inflate(R.menu.filter_tasks, menu)
setOnMenuItemClickListener {
viewModel.setFiltering(
when (it.itemId) {
R.id.active -> TasksFilterType.ACTIVE_TASKS
R.id.completed -> TasksFilterType.COMPLETED_TASKS
else -> TasksFilterType.ALL_TASKS
}
)
true
}
show()
}
}
...
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<import type="androidx.core.content.ContextCompat" />
<variable
name="viewmodel"
type="com.example.android.architecture.blueprints.todoapp.tasks.TasksViewModel" />
</data>
...
</layout>
如 docs 中所述:
View binding is a feature that allows you to more easily write code that interacts with views. Once view binding is enabled in a module, it generates a binding class for each XML layout file present in that module. An instance of a binding class contains direct references to all views that have an ID in the corresponding layout.
In most cases, view binding replaces
findViewById
.
看看粗体字,您会注意到视图绑定仅适用于 XML 布局(位于 res/layout
),而菜单位于 res/menu
.
此外,视图绑定使用 findViewById
,而菜单使用 menu.findItem(R.id.menu_id)
,因此这是不可能的。