Is there a way to pass data variable to included layout?
parent layout
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:showIn="#layout/fragment_settings">
<data>
<variable
name="viewModel"
type="......settings.SettingsFragmentViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:overScrollMode="never"
android:padding="#dimen/spacing_default">
<include
android:id="#+id/main"
layout="#layout/layout_settings_main" />
</androidx.constraintlayout.widget.ConstraintLayout>
and want to have viewModel in included layout
<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"
tools:showIn="#layout/fragment_settings">
<data>
<variable
name="viewModel"
type="......settings.SettingsFragmentViewModel" />
</data>
<merge>
...........
or is it possible only when setting like this:
binding = FragmentSettingsBinding.inflate(inflater, container, false).apply {
lifecycleOwner = this#SettingsFragment
viewModel = this#SettingsFragment.viewModel
main.viewModel = this#SettingsFragment.viewModel
}
In parent xml inside include tag pass data variable to included layout using bind:viewModel.
<?xml version="1.0" encoding="utf-8"?>
<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"
xmlns:bind="http://schemas.android.com/apk/res-auto"
tools:showIn="#layout/fragment_settings">
<data>
<variable
name="viewModel"
type="......settings.SettingsFragmentViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:overScrollMode="never"
android:padding="#dimen/spacing_default">
<include
android:id="#+id/main"
layout="#layout/layout_settings_main"
bind:viewModel="#{viewModel}" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your included layout will get object instance in viewModel.
For more details check this tutorial
Open build.grade and add dataBinding { enabled = true } in block android{ // ...}
Ok so, at the beginning of this article I’ve said that it depends whether it’s possible to pass the variable to a secondary layout or not. The reason for this is the following:
Data binding does not support include as a direct child of a merge element. For example, the following layout is not supported:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="it.communikein.myunimib.User"/>
</data>
<merge>
<include layout="#layout/name"
bind:user="#{user}"/>
<include layout="#layout/contact"
bind:user="#{user}"/>
</merge>
</layout>
Related
So the problem space is pretty simple.
I have a layout. Let's call it fragment1.xml and it looks like this.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="viewModel"
type="SomeViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/include_some_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="#layout/layout_consent_checkbox"
app:checkedData="#{viewModel.checkedData}" />
</LinearLayout>
</layout>
And let layout file layout_consent_checkbox.xml be this.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="checkedData"
type="Boolean" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="#+id/cb_some_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="#={checkedData}"
android:text="Plis check this?"/>
</LinearLayout>
</layout>
Now according to my knowledge, this should work. checkedData in SomeViewModel should be updating the Boolean value, based on the status change of the CheckBox. But it isn't getting updated. Please have a look and update me on what I'm doing wrong. Thanks!
I am trying to delay inflating some views in a large fragment to avoid a freeze.
in fragment.xml :
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="vm"
type="exm.ViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- some other views -->
<ViewStub
android:id="#+id/fragment_stub"
android:inflatedId="#+id/fragment_content"
android:layout="#layout/fragment_stub_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:vm="#{vm}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_stub_content.xml:
<?xml version="1.0" encoding="utf-8"?>
<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>
<variable
name="vm"
type="exm.ViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ACustomView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="#{()->vm.toggleDetails()}"
app:isExpanded="#{vm.canShowDetails}"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Function toggleDetails in vm toggles boolean livedata canShowDetails. I can see that this function is successfully called by a log. But canShowDetails (A MutableLiveData<Boolean>) does not change despite being observed in a view. A trivial code would be fragment_stub?.inflate() in my Fragment's onViewCreated() which is called successfully.
I have a layout as such:
<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>
<variable
name="viewModel"
type="com.myPackage.MyViewModel" />
</data>
<android.support.design.widget.CoordinatorLayout>
<include layout="#layout/modal_popup_view" />
</android.support.design.widget.CoordinatorLayout>
</layout>
How can I pass the variable viewModel into the included layout?
Define a viewModel (or any other named) variable in your #layout/modal_popup_view.
<data>
<variable
name="viewModel"
type="com.myPackage.PopupViewModel" />
</data>
In MyViewModel, expose the property popupViewModel of the type PopupViewModel. Pass the property to the included layout.
<include layout="#layout/modal_popup_view"
app:viewModel="#{viewModel.popupViewModel}" />
while integrating the BottomSheet we need to make the parent layout as the CoordinatorLayout but in databinding we use <layout>. While implementing this it throws an exception :-
Caused by: java.lang.IllegalArgumentException: The view is not a child of CoordinatorLayout.
How to integrate BottomSheet with databinding
<layout>
<data>
<import type="android.view.View" />
<variable
name="cabLayoutBinder"
type="newage.com.hopin.rideBooking.CabSelectActivity" />
<variable
name="modelBinder"
type="newage.com.hopin.rideBooking.model.DataBinders" />
<variable
name="fareSetters"
type="newage.com.hopin.rideBooking.model.FareDetails" />
</data>
<android.support.design.widget.CoordinatorLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".rideBooking.CabSelectActivity">
</android.support.design.widget.CoordinatorLayout>
</layout>
You put context in your coordinator, but in databinding you don't implement this way.
Try to remove this line and try again:
tools:context=".rideBooking.CabSelectActivity"
Let me know if it worked.
This is how I am using it
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".com.abc.Activity">
<data>
<variable
name="viewModel"
type=".com.abc.ViewModel" />
</data>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include
layout="#layout/toolbar" />
</FrameLayout>
<!-- Adding bottom sheet after main content -->
<include layout="#layout/bottom_sheet" />
</android.support.design.widget.CoordinatorLayout>
</layout>
I tried to use the me.tatarka.bindingcollectionadapter:bindingcollectionadapter library after I added it to gradle :
compile 'me.tatarka.bindingcollectionadapter:bindingcollectionadapter:1.3.0'
compile 'me.tatarka.bindingcollectionadapter:bindingcollectionadapter-recyclerview:1.3.0'
I used it in the xml file like this:
<layout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
>
<data>
<variable name="viewModel" type="com.example.ViewModel"/>
<import type="me.tatarka.bindingcollectionadapter.LayoutManagers" />
</data>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toStartOf="#+id/recycler"
app:layoutManager="#{LayoutManagers.linear()}"
app:items="#{viewModel.items}"
app:itemView="#{viewModel.itemView}"/>
</RelativeLayout>
</layout>
Identifiers must have user defined types from the XML file. LayoutManagers is missing it file
****\ data binding error ****
Could someone help me?
Thanks.
Data must be a children of layout
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable name="viewModel" type="com.example.ViewModel"/>
<import type="me.tatarka.bindingcollectionadapter.LayoutManagers" />
</data>
<!-- Rest of your layout -->
</layout>