Closed blonsky95 closed 3 years ago
Ok so basic rules are:
add to build.gradle in app:
buildFeatures {
dataBinding true
}
In the xml add a couple things:
<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">
to wrap all the layout code, so you can put under this component the data annotation/component just like this:
<data>
<variable
name="mainViewModel"
type="com.tatoeapps.tracktimer.viewmodel.MainViewModel" />
</data>
where name is the variable you are going to use in the binding activity, and type its type
In the activity:
val binding: com.tatoeapps.tracktimer.databinding.ActivityMainBinding =
DataBindingUtil.setContentView(this, layout.activity_main)
binding.mainViewModel = mainViewModel
binding.lifecycleOwner = this
where ActivityMainBinding is a self generated class by enabling binding and adding the code to the xml. It generates the name by doing "layout file name" -> to Pascal + Binding _e.g. mainactivity would be MainActivityBinding And DataBindingUtil is a binding normal class that has to be imported If a fragment, the lifecycleOwner should be getLifecycleOwner
In this example the text of a textview has the following value
android:text="@{mainViewModel.timingDisplayText}"
which is a livedata field, and is working well
So, to add a method in onClick, as usually you are not interested in the view parameter that comes with it, you can do this:
android:onClick="@{() -> actionButtonsInterface.importVideo()}"
And to implement databinding in a fragment there is a slight difference:
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentActionBtnsBinding.inflate(inflater, container, false)
fragmentActionBtnsBinding = binding
binding.actionButtonsInterface=mActionButtonsInterface
return binding.root
}
and
override fun onDestroyView() {
fragmentActionBtnsBinding=null
super.onDestroyView()
}
First the binding variable is created through inflate
Then to account for the lifecycle awareness there is a variable (fragmentActionBtnsBinding) which is initialised to null, and when view is destroyed is set to null again, aka, when no fragment, no binding.
Then the variable in xml (the field in
For Livedata binding, I initialise the data as livedata, and then I postvalue to it like normally, but this livedata isnt observed anywhere. But remember to also add:
binding.lifecycleOwner=viewLifecycleOwner
or "this" if it is an activity (the example is from a fragment)
Starting using LiveData with Data Binding To use a LiveData object with your binding class, you need to specify a lifecycle owner to define the scope of the LiveData object.
First for data binding:
use it for speed number to be updated directly through that - fragment is already doing that - not through viewmodel
visibility of player_controls which is the play, forward, rewind next, previous frame buttons - not really good idea, it works together with the fragments and the livedata just sends a tap notification, not the actual visibility state that should be applied
can i use it for the timing info layout as well? so the text --> Yes the text is being updated through data binding with livedata
Try binding ActionButtonsFragment to its xml, it doesnt need a viewmodel, it isnt observing livedata, so just bind them together and then use the interface variable - DONE
Try with speed interface if something can be done with databinding - DONE