片段和 activity 之间的数据绑定行为异常
Data binding behaving unexpected between fragments and activity
所以我想弄清楚为什么我不能覆盖数据绑定 属性 mainActivity.toolbarViewConfig.title.value = "help me please"
。 属性 似乎只设置了一次,这将在我的 activity 或片段 A 中起作用。如果我尝试在片段 B 中给 属性 一个值,那将不起作用.如果我尝试通过为 activity 中的按钮设置点击侦听器来覆盖 属性,那是行不通的。很明显,绑定似乎发生了一些奇怪的事情。各种建议将不胜感激。我已经连续 4 天坐着挠头了。请帮助我不要成为秃头。
Activity:
override fun onCreate(savedInstanceState: Bundle?) {
requestWindowFeature(Window.FEATURE_NO_TITLE)
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.toolbarViewConfig = toolbarViewConfig
setContentView(binding.root)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar).setupWithNavController(navController,appBarConfiguration)}
片段 A:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val mainActivity = activity!! as MainActivity
mainActivity.toolbarViewConfig.title.value = "This works!" //Works fine.
return inflater.inflate(R.layout.fragment_home, container, false)
}
片段 B:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
val viewModel = ViewModelProvider(this).get(GoOnlineViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentSellerGoOnlineBinding>(
inflater, R.layout.fragment_seller_go_online,
container, false
).apply {
this.lifecycleOwner = viewLifecycleOwner
this.viewModel = viewModel}
val mainActivity = activity!! as MainActivity
mainActivity.toolbarViewConfig.title.value = "This does not work" //When I navigate from Fragment A to B this will not be set
viewModel.navigationCommand.observe(viewLifecycleOwner, Observer {
when(it) {
is NavigationCommand.To ->
Navigation.findNavController(requireView()).navigate(it.directions)
}
})
return binding.root
}
工具栏视图配置:
class ToolbarViewConfig(
var title: MutableLiveData<String> = MutableLiveData(""))
activity_main.xml:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable
name="toolbarViewConfig"
type="my.app.willow.models.ToolbarViewConfig" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{toolbarViewConfig.title}"
android:layout_gravity="center"
android:id="@+id/toolbar_title"/>
</androidx.appcompat.widget.Toolbar>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
您忘记在 ActivityMainBinding
中分配 lifecycleOwner
。没有它,您的 Activity
将永远不会监听更改,只会读取一次当前值。
我相信 FragmentA
在 ActivityMainBinding.inflate(layoutInflater)
期间创建了它的视图并设置了标题。所以在下一行中当你在你的ActivityMainBinding
中设置toolbarViewConfig
时,它已经可以读取标题的初始值LiveData
(由FragmentA
设置),但永远不会对 FragmentB
.
中所做的任何后续更改做出反应
所以我想弄清楚为什么我不能覆盖数据绑定 属性 mainActivity.toolbarViewConfig.title.value = "help me please"
。 属性 似乎只设置了一次,这将在我的 activity 或片段 A 中起作用。如果我尝试在片段 B 中给 属性 一个值,那将不起作用.如果我尝试通过为 activity 中的按钮设置点击侦听器来覆盖 属性,那是行不通的。很明显,绑定似乎发生了一些奇怪的事情。各种建议将不胜感激。我已经连续 4 天坐着挠头了。请帮助我不要成为秃头。
Activity:
override fun onCreate(savedInstanceState: Bundle?) {
requestWindowFeature(Window.FEATURE_NO_TITLE)
super.onCreate(savedInstanceState)
val binding = ActivityMainBinding.inflate(layoutInflater)
binding.toolbarViewConfig = toolbarViewConfig
setContentView(binding.root)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar).setupWithNavController(navController,appBarConfiguration)}
片段 A:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val mainActivity = activity!! as MainActivity
mainActivity.toolbarViewConfig.title.value = "This works!" //Works fine.
return inflater.inflate(R.layout.fragment_home, container, false)
}
片段 B:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
val viewModel = ViewModelProvider(this).get(GoOnlineViewModel::class.java)
val binding = DataBindingUtil.inflate<FragmentSellerGoOnlineBinding>(
inflater, R.layout.fragment_seller_go_online,
container, false
).apply {
this.lifecycleOwner = viewLifecycleOwner
this.viewModel = viewModel}
val mainActivity = activity!! as MainActivity
mainActivity.toolbarViewConfig.title.value = "This does not work" //When I navigate from Fragment A to B this will not be set
viewModel.navigationCommand.observe(viewLifecycleOwner, Observer {
when(it) {
is NavigationCommand.To ->
Navigation.findNavController(requireView()).navigate(it.directions)
}
})
return binding.root
}
工具栏视图配置:
class ToolbarViewConfig(
var title: MutableLiveData<String> = MutableLiveData(""))
activity_main.xml:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View"/>
<variable
name="toolbarViewConfig"
type="my.app.willow.models.ToolbarViewConfig" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{toolbarViewConfig.title}"
android:layout_gravity="center"
android:id="@+id/toolbar_title"/>
</androidx.appcompat.widget.Toolbar>
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
您忘记在 ActivityMainBinding
中分配 lifecycleOwner
。没有它,您的 Activity
将永远不会监听更改,只会读取一次当前值。
我相信 FragmentA
在 ActivityMainBinding.inflate(layoutInflater)
期间创建了它的视图并设置了标题。所以在下一行中当你在你的ActivityMainBinding
中设置toolbarViewConfig
时,它已经可以读取标题的初始值LiveData
(由FragmentA
设置),但永远不会对 FragmentB
.