Android ViewPager';协调器布局中的高度超过可用高度
我有一个Android ViewPager';协调器布局中的高度超过可用高度,android,android-layout,android-viewpager,android-coordinatorlayout,Android,Android Layout,Android Viewpager,Android Coordinatorlayout,我有一个坐标布局,在AppBarLayout中有一个工具栏和一个表格布局。此外,我在坐标布局内有一个查看页面,但在查看页面外 问题是ViewPager的高度大于实际可用的高度,导致我的片段中的一些视图被剪切 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res
坐标布局
,在AppBarLayout
中有一个工具栏
和一个表格布局
。此外,我在坐标布局
内有一个查看页面
,但在查看页面
外
问题是ViewPager的
高度大于实际可用的高度,导致我的片段
中的一些视图被剪切
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/lightGray"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar2"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:scrollbars="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="false"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
一个可能的破解方法是添加与工具栏相同的底部边距,即
?attr/actionBarSize。你甚至可以摆弄其他可能的用户界面空白,给你最好的结果 我花了很多时间在谷歌上搜索和应用建议答案,但没有成功,所以我决定深入研究这个问题,找出一个完整的答案,我想在这里与大家分享。也许它会帮助别人
因此,问题是当ViewPager与折叠工具栏一起使用时,第一个工具栏无法正确计算其高度。如果您希望查看页面填满屏幕底部的所有空间,但不能超过此空间,则会出现问题。仅仅添加layout\u marginBottom
并不能解决这个问题,因为折叠工具栏会在用户滚动时改变其高度
因此,如果您希望您的ViewPager根据折叠工具栏的高度变化调整其高度,您需要两件事:
自定义滚动行为
GlobalLayoutListener,它将在第一次绘制ViewPager时固定其高度
它们在这里(用Kotlin编写,但它只是一个单独的文件,可以直接放入Java项目中):
并在代码中使用它们:
将自定义行为添加到您的ViewPager:应用程序:layout\u behavior=“your.package.ViewPagerScrollingBehavior”
将自定义OnGlobalLayoutListener添加到您的ViewPager:ViewPager.getViewTreeObserver().addOnGlobalLayoutListener(新的固定高度GlobalLayoutListener(此,ViewPager))代码>
根据耶夫赫尼的上述回答,我想我设法以一种更简单的方式解决了这个问题:
class KeepWithinParentBoundsScrollingBehavior : AppBarLayout.ScrollingViewBehavior {
constructor() : super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
if (dependency !is AppBarLayout) {
return super.onDependentViewChanged(parent, child, dependency)
}
val layoutParams = child.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.height = parent.height - dependency.bottom
child.layoutParams = layoutParams
return super.onDependentViewChanged(parent, child, dependency)
}
}
然后在ViewPager
或AppBar
下方的任何视图上设置app:layout\u behavior=“your.package.keepwhithinparentboundsScrollingBehavior”
请注意,这不是适用于所有CoordinatorLayout
s的通用解决方案,但当您在应用程序栏下方有一个视图,而您不希望该视图延伸到父CoordinatorLayout的底部之外时,它似乎可以工作
更新:
您还应该在ViewPager上设置app:layout\u anchor=“@id/app\u bar”
,以适应键盘消失的情况。如果您不这样做,ViewPager
布局将不会在键盘消失时刷新,ViewPager
将显示为被切断。可能重复的请查看我的解释,这样做解决了高度错误的问题,但所有滚动效果都被删除。还有,在没有“滚动”的情况下使用“enterAlways”有什么意义?我认为为了使用“enterAlways | snap | etc”滚动是必须的,实际上删除layout|u scrollFlags属性将解决高度问题。因为滚动对于任何滚动都是必须的。此解决方案受可能的重复影响更大。因为感觉很奇怪,同样的设置对其他人也不起作用。如果你想保持滚动,那么有一个轻微的黑客,我想请你试试,因为错误的高度几乎等于工具栏的高度。尝试将底部边距设置为?attr/actionBarSize,并将滚动标志保留为原始标志。如果这给了你满意的结果,我会更新这个答案。尝试在查看页面中建议的底部边距。添加边距可以修复它。我建议使用与表格布局高度相同的边距,以便更准确。因此,不要使用height=“wrap\u content”而是使用height=“x”并使用x作为查看页面的底部边距。谢谢。很高兴它对你有用。我更新了答案以反映最终解决方案,请考虑接受和接受。祝你好运:)我想,viewPager
和mViewPager
有什么不同?没有区别:)只是忘了重命名我解决了这个问题,没有使用GlobalLayoutListener
。见下面我的答案
class KeepWithinParentBoundsScrollingBehavior : AppBarLayout.ScrollingViewBehavior {
constructor() : super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun onDependentViewChanged(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
if (dependency !is AppBarLayout) {
return super.onDependentViewChanged(parent, child, dependency)
}
val layoutParams = child.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.height = parent.height - dependency.bottom
child.layoutParams = layoutParams
return super.onDependentViewChanged(parent, child, dependency)
}
}