28

我有一个经典的布局,顶部有一个 ToolBar,下面有一个 TabLayout,还有一个 ViewPager 从 TabLayout 切换选项卡。当 ViewPager 中的内容可滚动时,ToolBar 应该滚动到视线之外,并且 TabLayout 应该跟随并在到达顶部时粘住。

在我当前的代码中,这一切都很好,除了 ToolBar 始终是可滚动的,无论 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:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.ToolBar"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:scrollbars="horizontal"
            app:tabIndicatorColor="@color/black_text" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/tabs_activity_view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

编辑:

我可以看到 viewPager 的高度与整个根视图的高度相同。这可能是有意的,因为 appbar_scrolling_view_behavior 似乎确实添加了顶部和底部偏移量。然而,它确实看起来很奇怪,因为它会导致总是滚动工具栏和标签栏。

4

8 回答 8

8

我已经解决了这个问题,尝试了示例 Google 模板并发现

app:layout_behavior="@string/appbar_scrolling_view_behavior" 

必须将行添加到视图寻呼机属性 xml 中。它解决了我的问题。

于 2018-01-13T15:57:15.323 回答
7

我建议你试试这个样本。

这是一个类似于您在示例中的布局的布局。

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done" />

</android.support.design.widget.CoordinatorLayout>
于 2015-10-31T05:59:18.207 回答
3

使用 ListView 作为 ViewPager 的数据?如果是这样,你需要listView.setNestedScrollingEnabled(true);

于 2017-03-19T16:09:59.780 回答
0

尝试在 TabLayout 上添加这些属性:

 app:layout_collapseMode="pin"
 app:tabMode="fixed"

这在 AppBarLayout 上:

 android:fitsSystemWindows="true"

* 更新 *

我试过了,这还不够,因为工具栏仍然可以滚动。解决方案是对 ViewPager(及其内容)进行一些逻辑处理。

从 xml 布局文件中删除工具栏 scroll_flag 属性。您必须实现一些 java 代码来检查 ViewPager 内容高度是否 > 然后 screenHeight - (toolbar + tabBar)。如果为 true,则以编程方式将 scroll_flags 设置为:

 LayoutParams params;
 params = // get layout params from your toolbar

 params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
| AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS);

 // set params
 toolbar.setLayoutParams(params);
于 2015-09-18T09:13:40.703 回答
0

基于其他示例、我自己的代码以及 appbar_scrolling_view_behavior 的(有些混乱的)源代码:

        public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
            View dependency) {
        final CoordinatorLayout.Behavior behavior =
                ((CoordinatorLayout.LayoutParams) dependency.getLayoutParams()).getBehavior();
        if (behavior instanceof Behavior) {
            // Offset the child so that it is below the app-bar (with any overlap)

            final int appBarOffset = ((Behavior) behavior)
                    .getTopBottomOffsetForScrollingSibling();
            final int expandedMax = dependency.getHeight() - mOverlayTop;
            final int collapsedMin = parent.getHeight() - child.getHeight();

            if (mOverlayTop != 0 && dependency instanceof AppBarLayout) {
                // If we have an overlap top, and the dependency is an AppBarLayout, we control
                // the offset ourselves based on the appbar's scroll progress. This is so that
                // the scroll happens sequentially rather than linearly
                final int scrollRange = ((AppBarLayout) dependency).getTotalScrollRange();
                setTopAndBottomOffset(AnimationUtils.lerp(expandedMax, collapsedMin,
                        Math.abs(appBarOffset) / (float) scrollRange));
            } else {
                setTopAndBottomOffset(dependency.getHeight() - mOverlayTop + appBarOffset);
            }
        }
        return false;
    }

我正在以解释问题的方式阅读本文,因为这是此代码的预期行为。

我认为我们需要编写自己的滚动行为,特别是针对 RecyclerView,

于 2015-11-01T10:06:40.477 回答
-1

我刚刚遇到了同样的问题。解决方法很简单,只要设置你的viewpager高度

android:layout_height="wrap_content"
于 2016-05-31T02:56:11.430 回答
-1

ViewPager高度应该是而match_parent不是wrap_content

于 2015-10-31T14:01:20.913 回答
-2

简单的解决方案是 - 用相对布局包装您的 appbar 布局和页面查看器。- 给你的 appbar 布局一些 id - 在页面视图中设置 android:layout_below="Your_appbar_layout" 例如:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<android.support.design.widget.AppBarLayout
    android:id="@+id/your_appBar_ID"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.ToolBar"
        app:layout_scrollFlags="scroll|enterAlways" />

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:scrollbars="horizontal"
        app:tabIndicatorColor="@color/black_text" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/tabs_activity_view_pager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/your_appBar_ID"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</RelativeLayout>

于 2016-08-18T16:18:54.750 回答