Reputation: 38
So I'm trying to figure out why I can't override a data bound property mainActivity.toolbarViewConfig.title.value = "help me please"
. The property seems to be set only once and this will either work in my activity or in Fragment A. If I try to give the property a value in Fragment B, that would not work. If I try to override the property by setting a click-listener for a button in the activity, that would not work. So obviously there seems to be something strange going on with the binding. All kind of suggestions would be appreciated. I have been sitting scratching my head 4 days in a row. Please help me not become bald.
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)}
Fragment 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)
}
Fragment 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
}
ToolbarViewConfig:
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>
Upvotes: 1
Views: 567
Reputation: 10715
You forgot to assign a lifecycleOwner
in your ActivityMainBinding
. Without it, your Activity
will never listen for changes and will just read the current value once.
I believe that FragmentA
creates it's view and sets the title during ActivityMainBinding.inflate(layoutInflater)
. So in the next line when you set up toolbarViewConfig
in your ActivityMainBinding
, it can already read the initial value of the title LiveData
(set by FragmentA
), but will never react to any later changes done in FragmentB
.
Upvotes: 1