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>
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.
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>
I have the following activity 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">
<data>
<import type="com.aurelhubert.ahbottomnavigation.AHBottomNavigation" />
<variable
name="viewModel"
type="[...]android.ui.MainViewModel" />
</data>
<RelativeLayout
android:id="#+id/wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottom_navigation" />
<com.aurelhubert.ahbottomnavigation.AHBottomNavigation
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="#dimen/bottom_navigation_height"
android:layout_alignParentBottom="true"
app:accentColor="#color/bottomNavActive"
app:defaultBackgroundColor="#{#color/bottomNavBg}"
app:inactiveColor="#color/bottomNavInactive"
app:titleState="#{AHBottomNavigation.TitleState.ALWAYS_SHOW}"
app:useElevation="#{false}" />
<FrameLayout
android:id="#+id/floating_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
</RelativeLayout>
</layout>
And a fragment that is displayed in FrameLayout:
<?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="viewModel"
type="[...]android.ui.home.jobs.JobsViewModel" />
<variable
name="navigationViewModel"
type="[...]android.ui.NavigationViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="#dimen/extended_toolbar_height"
android:theme="#style/AppBarLayoutTheme">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:expandedTitleMarginBottom="#dimen/extended_toolbar_title_margin_bottom"
app:expandedTitleMarginEnd="#dimen/content_indent_end"
app:expandedTitleMarginStart="#dimen/content_indent_start"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:title="#string/jobs_title" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:itemBinding="#{viewModel.itemBinding}"
app:items="#{viewModel.items}"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
The whole fragment should be displayed above the AHBottomNavigation as folows:
Desired state
However, sometimes when switching tabs or rotating screen the result is as folows (content is overlapped by the bottom navigation; cannot scroll more):
Bottom menu overlapping the content
It seems that the root of the issue is somehow in the CollapsingToolbarLayout, not the AHBottomNavigation (does not work even if AHBottomNavigation is replaced by something else).
Do you have any idea where could be the problem? Thanks for any suggestions.
I am using concept of Databinding-mvvm to implement such things. I have declared recyclerview into the my mainactivity. like
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<variable
name="ffvm"
type="com.example.the_king.apartmentmanagementsystem.ViewModal.
FragmentViewModal.ViewModal"/>
</data>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.the_king.apartmentmanagementsystem.
Fragment.Fragment_FlatHolder">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
</layout>
my cardview is look like
<layout>
<data>
<import type="android.view.View"/>
<variable
name="cfhvm"
type="com.example.the_king.apartmentmanagementsystem.ViewModal.
CardViewModel.CardViewModal"/>
</data>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.the_king.apartmentmanagementsystem.
CardView.CardViewFlatHolder"
layout_width="match_parent"
android:background="#color/colorPrimaryLight"
android:elevation="25dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:innerRadius="15dp"
android:thicknessRatio="1.9"
layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{cfhvm.firstname+` `+cfhvm.lastname}"
android:layout_marginLeft="5dp"
android:textSize="#dimen/text_title"
/>
</android.support.v7.widget.CardView>
</layout>
for the cardview i have created viewmodel as cardviewmodal and for Recyclerview i have created viewmodel and i have also created adapter to fill data now i got confuse how do i set value of recyclerview from the viewmodel which contains cardviewmodel.