Coordinatorlayout 中的 VIewpager 在可见性消失时占用了额外的空间

Posted

技术标签:

【中文标题】Coordinatorlayout 中的 VIewpager 在可见性消失时占用了额外的空间【英文标题】:VIewpager inside Coordinatorlayout takes extra space on visibility gone 【发布时间】:2021-04-04 16:43:24 【问题描述】:

我有一个布局,我需要工具栏的上部和一些内容,然后是 ViewPager 的下部,需要根据布尔值隐藏。

XML 的骨架如下所示:

 <LinearLayout
        android:layout_
        android:layout_
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:layout_
            android:layout_/>

        <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_
            android:layout_>

            <com.google.android.material.appbar.AppBarLayout
                android:layout_
                android:layout_>

                <com.google.android.material.appbar.CollapsingToolbarLayout
                    android:layout_
                    android:layout_
                    app:expandedTitleGravity="bottom|center_horizontal"
                    app:layout_scrollFlags="scroll">

                    <androidx.constraintlayout.widget.ConstraintLayout
                        android:layout_
                        android:layout_
                        app:layout_collapseMode="none">

                        <TextView
                            style="@style/Medium.ExtraLarge"
                            android:layout_
                            android:layout_
                            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_
                android:layout_
                android:visibility="@(viewModel.isInBusinessManagement &amp;&amp; (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_
                    android:layout_
                    android:background="@drawable/tab_background_2dp"
                    android:visibility="@(viewModel.isInBusinessManagement &amp;&amp; (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>


如您所见,我必须根据布尔值控制 ViewPagerTabLayout 的可见性,为此我正在使用数据绑定。

布局都很好,当需要显示时,我得到了预期的行为,但问题是当提到的条件时,即。 viewModel.isInBusinessManagement &amp;amp;&amp;amp; (viewModel.hasActivePremium || viewModel.hasSuspendedPlan) 为 false,Viewpager 和 TabLayout 不可见,但占用的空间与可见时一样多。

现在我知道View.INVISIBLE 具有这种行为,但我显然将View.GONE 用于false 案例。

此外,当我在根LinearlayoutAppbarLayoutCoordinatorLayout 上放置不同的颜色时,底部的额外空间似乎来自CoordinatorLayout

你能帮我解决这个问题吗?

【问题讨论】:

您可以尝试将ViewPager 放在FrameLayout 中,然后将app:layout_behavior 从寻呼机转移到此布局.. 不确定这是否有助于将其作为答案发布 @Zain 我做到了,没有运气。多余的空间还在 记住一点:当你隐藏这些视图时,你能以编程方式从ViewPager 中删除app:layout_behavior,当你再次显示它们时,再次添加行为.. 我认为这个空间是由于CoordinatorLayout Behavior.. 如果您需要帮助,请告诉我 @Zain 是的,我确实怀疑额外的空间是由于CoordinatorLayout 行为造成的。尝试在视图GONE 上从viewpager 中删除app:layout_behavior 并再次以编程方式在视图VISIBLE 上附加相同的内容是值得的,但我找不到任何方法来做到这一点。如果可以的话,请帮帮我。 删除它:ViewPager viewpager = findViewById(R.id.viewpager); CoordinatorLayout.LayoutParams coordinatorParams = (CoordinatorLayout.LayoutParams) viewpager.getLayoutParams(); coordinatorParams.setBehavior(null); 【参考方案1】:

我尝试在本地解决此问题,以下代码对我有用。你也可以试试这个:

    制作一个包含可见性逻辑的绑定适配器。

@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/>
    
    所有 3 个视图模型变量都是布尔类型的可变实时数据。
    var isInBusinessManagement = MutableLiveData<Boolean>()
    var hasActivePremium = MutableLiveData<Boolean>()
    var hasSuspendedPlan = MutableLiveData<Boolean>()
    由于选项卡布局在视图分页器中并且两者具有相同的可见性逻辑,所以在 XML 中我只控制视图分页器的可见性。
    <androidx.viewpager.widget.ViewPager
                android:id="@+id/vpager"
                android:layout_
                android:layout_
                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

    并使CoordinatorLayout的高度为wrap_parent

我认为只有从第 5 步更改,您才能在现有代码中实现结果。以上 4 个步骤是为了更好地利用数据绑定,通过在绑定适配器中编写逻辑。

【讨论】:

这个答案虽然得到了赏金,但是这个答案并没有解决问题【参考方案2】:

viewpager visibility 消失时,也许这可以让您停止滚动工具栏

layout_scrollFlags 中的noScroll 标志将停止滚动CollapsingToolbarLayout

<com.google.android.material.appbar.CollapsingToolbarLayout
     android:layout_
     android:layout_
     app:expandedTitleGravity="bottom|center_horizontal"
     app:layout_scrollFlags="@(viewModel.isInBusinessManagement &amp;&amp; (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)) ? scroll : noScroll">

【讨论】:

无法导入 ScrollFlags 以使用 scrollnoScroll,就像使用 ViewView.GONEView.VISIBLE 一样可以做到这一点 执行val params = layoutViewPager.collapsing.layoutParams as AppBarLayout.LayoutParams; params.scrollFlags = 0; layoutViewPager.collapsing.layoutParams = params 也无济于事 这可能对你有帮助:***.com/questions/31179435/…

以上是关于Coordinatorlayout 中的 VIewpager 在可见性消失时占用了额外的空间的主要内容,如果未能解决你的问题,请参考以下文章

CoordinatorLayout_Behavior控制Toolbar&Fab的显示和隐藏

CoordinatorLayout使用详解: 打造折叠悬浮效果

CoordinatorLayout/AppbarLayout/CollapsingToolbarLayout的配合使用,Toolbar特效

android CoordinatorLayout使用

android CoordinatorLayout使用

CoordinatorLayout原理的简析