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

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

XML 的骨架如下所示:

 <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 &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_width="match_parent"
                    android:layout_height="wrap_content"
                    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);

标签: android android-layout android-viewpager android-coordinatorlayout


【解决方案1】:

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

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

  1. 确保在使用具有数据绑定的视图模型时附加了生命周期所有者。
    binding.viewModel = viewModel
    binding.lifecycleOwner = this

  1. 并使CoordinatorLayout的高度为wrap_parent

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

【讨论】:

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

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

layout_scrollFlags 中的noScroll 标志将停止滚动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 &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 也无济于事
  • 这可能对你有帮助:stackoverflow.com/questions/31179435/…
猜你喜欢
  • 2019-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多