Reputation: 1001
I have a layout whereby I need the an upper section of toolbar and some content and then a lower section of ViewPager
which needs to be hidden based on a boolean value.
The skeleton of the XML looks like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?actionBarSize"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expandedTitleGravity="bottom|center_horizontal"
app:layout_scrollFlags="scroll">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="none">
<TextView
style="@style/Medium.ExtraLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
tools:text="Title Something" />
<!--Other top section content -->
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="@{(viewModel.isInBusinessManagement && (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)) ? View.VISIBLE : View.GONE}"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layout_collapseMode="pin"
tools:visibility="gone">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/tab_background_2dp"
android:visibility="@{(viewModel.isInBusinessManagement && (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)) ? View.VISIBLE : View.GONE}"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/colorPrimary"
app:tabTextAppearance="@style/tab_text"
app:tabTextColor="@color/txtColorGrey" />
</androidx.viewpager.widget.ViewPager>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
As you can see I have to control the visibility of the ViewPager
and TabLayout
based on boolean values, I am using databinding for that.
The layout is all good and I get the expected behavior when it needs to be shown but the issue is that when the conditions mentioned ie. viewModel.isInBusinessManagement && (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)
is false, the Viewpager and TabLayout is invisible but takes up as much space as it did when it was visible.
Now I know that View.INVISIBLE
has that behavior but I am clearly using View.GONE
for false
case.
Also when I put different colors on the root Linearlayout
, AppbarLayout
and CoordinatorLayout
, the extra space on the bottom seems to be coming from CoordinatorLayout
.
Could you please help me with this?
Upvotes: 0
Views: 694
Reputation: 370
I tried to solve this locally, and the following code worked for me. You can also try this:
@BindingAdapter(value = ["hasActivePremium", "isInBusinessManagement", "hasSuspendedPlan"], requireAll = true)
fun controlVPVisibility(view: ViewPager, hasActivePremium: Boolean, isInBusinessManagement:Boolean, hasSuspendedPlan:Boolean) {
view.visibility = if(isInBusinessManagement && (hasActivePremium || hasSuspendedPlan)) View.VISIBLE else View.GONE````<br/>
}
var isInBusinessManagement = MutableLiveData<Boolean>()
var hasActivePremium = MutableLiveData<Boolean>()
var hasSuspendedPlan = MutableLiveData<Boolean>()
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/teal_700"
isInBusinessManagement="@{viewModel.isInBusinessManagement()}"
hasActivePremium="@{viewModel.hasActivePremium}"
hasSuspendedPlan="@{viewModel.hasSuspendedPlan}"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layout_collapseMode="pin">
binding.viewModel = viewModel
binding.lifecycleOwner = this
wrap_parent
I think only from the 5th step change, you can achieve the result in your existing code. The above 4 steps are to make better use of data binding by writing logic in the binding adapter.
Upvotes: 1
Reputation: 3699
maybe this work for you to stop scrolling toolbar when viewpager
visibility
is gone
noScroll
flag in layout_scrollFlags
will stop scrolling CollapsingToolbarLayout
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:expandedTitleGravity="bottom|center_horizontal"
app:layout_scrollFlags="@{(viewModel.isInBusinessManagement && (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)) ? scroll : noScroll}">
Upvotes: 0