【发布时间】:2019-11-30 16:07:57
【问题描述】:
我有一个主要活动 ConstraintLayout,它需要在顶部 AppbarLayout 下方左侧可见的区域中显示 ViewPager LiveData,该区域包含 ViewPager 的滚动 TabLayout 项目名称。我的困难是 ViewPager 片段文本的顶部被 AppbarLayout 工具栏和选项卡遮住了。我正在尝试将 ViewPager 数据限制为显示在 AppbarLayout 区域下方。
这我可以在 AS 自带的 TabLayout 活动模板中做,当 TabLayout 单独时它可以正常工作。不幸的是,我的 Activity 还迎合了 DrawerLayout NavigationView 菜单,而 Drawer 和 ViewPager 交替响应滑动的唯一方法是当我将 ViewPager 嵌套在 DrawerLayout 中,放置在其 NavigationView 之前。所以我的 ViewPager 已经在 XML 规范底部的 ActivityLayout 中的 DrawerLayout 中关闭了:
<ConstraintLayout
...
<androidx.drawerlayout.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
app:layout_constraintTop_toBottomOf="@+id/cal_appbar">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:visibility="visible">
</androidx.viewpager.widget.ViewPager>
<com.google.android.material.navigation.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_refresh"
app:menu="@menu/activity_calib_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
</ConstraintLayout>
在它和我显示省略号的根标记之间,ConstraintLayout 有一个 AppbarLayout,其中包含 Toolbar 和 TabLayout,然后是用于其他 Fragment 的 RelativeLayout。问题不涉及RelativeLayout但AppbarLayout重叠ViewPager的显示
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/cal_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay"
android:fitsSystemWindows="true"
tools:context=".Calibsense"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/cal_toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="@color/colorPrimary"
android:visibility="visible"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" >
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?actionBarSize"
android:padding="@dimen/appbar_padding_top"
android:text="@string/intro_name"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"/>
</androidx.appcompat.widget.Toolbar>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:visibility="visible"
app:layout_constraintTop_toBottomOf="@id/cal_appbar">
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/overlap">
...
</RelativeLayout>
...
</ConstraintLayout>
ConstraintLayout 坚持约束同级,所以我上面的约束指定包含视图 DrawerLayout 约束 AppbarLayout 而不是最终目标:ViewPager 与 TabLayout。
是否有约束启发式可用于指定片段(ViewPager)显示在 AppbarLayout-TabLayout 下方?
作为一种可能的解决方法,有没有办法为 ViewPager 指定一个顶部填充,其高度为 AppbarLayout 以将其内容推送到可视区域?
我也曾考虑尝试使用 CollapsingToolbarLayout,但设法显示整个 ViewPager 完全没有 AppBarLayout。
附录:
进一步查看在 Activity 的 onCreate() 方法调用 setGuide() 期间对上述内容的编程调用,我在下面公开了 AppbarLayout 参数,并且调试器向我显示了与 XML 设置相同的值:高度 -1 (match_parent)和宽度 -2 (wrap_content),并且在 setGuide() 末尾使用子视图展开后,该值保持不变。测量高度始终显示为零。我不知道这些值的意义;我希望看到几何值,例如非零 px / dp 数量。任何人都可以解释一下吗?零测量高度是否也意味着 ViewPager 被锚定在 px (0,0),如果是这样,如何将锚 y 值更改为低于 AppbarLayout 的可见底部?但我需要首先以编程方式提取该值。如何实现?
DrawerLayout drwLyt;
SectionsPagerAdapter sectionsPagerAdapter;
ViewPager viewPager;
AppBarLayout aBL;
CollapsingToolbarLayout cTBL;
TabLayout tabs;
TextView title;
ConstraintLayout mainGuideView;
Calibsense guideParent;
void setGuide(Calibsense guideModule){
guideParent = guideModule;
// AppbarLayout
aBL = guideParent.findViewById(R.id.cal_appbar);
ViewGroup.LayoutParams aBLParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
aBL.setLayoutParams(aBLParams);
aBL.setExpanded(true);
// measure AppbarLayout using params copy of internal value
ViewGroup.LayoutParams appBarLayoutParams = aBL.getLayoutParams();
int aBLHeight = appBarLayoutParams.height;
int aBLmHeight = aBL.getMeasuredHeight();
drwLyt = findViewById(R.id.drawer_layout);
ViewGroup.LayoutParams drawerLayoutParams = drwLyt.getLayoutParams();
int drwLytHeight = drawerLayoutParams.height;
// setting-up of viewPager
sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
viewPager = findViewById(R.id.view_pager);
// this could be redundant,
// somewhere it was suggested a new LayoutParams() is required
ViewGroup.LayoutParams viewPagerParams = viewPager.getLayoutParams();
viewPager.setAdapter(sectionsPagerAdapter);
int viewPagerHeight = viewPager.getHeight();
View spacerView = findViewById(R.id.pager_spacer);
int spacerHeight = spacerView.getHeight();
spacerView.setMinimumHeight(aBLHeight);
// Start set-up of tabs
TabLayout tabs = findViewById(R.id.tabs);
// complete set-up of tabs by insertion of viewPager
tabs.setupWithViewPager(viewPager);
int tabsHeight = tabs.getHeight();
relL.setVisibility(View.INVISIBLE);
// measure AppbarLayout using params copy of internal value
appBarLayoutParams = aBL.getLayoutParams();
aBLHeight = appBarLayoutParams.height;
aBLmHeight = aBL.getMeasuredHeight();
}
【问题讨论】:
标签: android-viewpager drawerlayout android-appbarlayout