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 && (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 && (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>
如您所见,我必须根据布尔值控制 ViewPager
和 TabLayout
的可见性,为此我正在使用数据绑定。
布局都很好,当需要显示时,我得到了预期的行为,但问题是当提到的条件时,即。 viewModel.isInBusinessManagement &amp;&amp; (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)
为 false,Viewpager 和 TabLayout 不可见,但占用的空间与可见时一样多。
现在我知道View.INVISIBLE
具有这种行为,但我显然将View.GONE
用于false
案例。
此外,当我在根Linearlayout
、AppbarLayout
和CoordinatorLayout
上放置不同的颜色时,底部的额外空间似乎来自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 && (viewModel.hasActivePremium || viewModel.hasSuspendedPlan)) ? scroll : noScroll">
【讨论】:
无法导入ScrollFlags
以使用 scroll
和 noScroll
,就像使用 View
、View.GONE
和 View.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特效