使用折叠式工具栏和标签进行滚动

12

我正在尝试使用CollapsingToolbarLayout创建一个布局,它具有scroll|exitUntilCollapsed标志和一个带有scroll|enterAlways滚动标志属性的TabLayout。基本上,我希望我的工具栏固定并在滚动时显示和隐藏选项卡。我修改了https://github.com/chrisbanes/cheesesquare应用程序中的内容。这是我的布局xml;

<?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:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

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

    </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:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_discuss"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

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

这是结果:

选项卡没有正确定位。 并且它们不关心enterAlways属性。

输入图像描述


1
@BhaveshPatadiya 是的。在AppBar下方。 - syloc
还有一个澄清,为了简化 - 期望的滚动行为是什么? 是这样吗:首先图像以完整高度可见,然后向工具栏滚动。进一步滚动会隐藏选项卡并保留工具栏? - DmitryArc
尝试将您的TabLayout直接放置在AppBarLayout的子级,而不是放在CollapsingToolbarLayout内部。 - hidro
抱歉Syloc,我知道你已经回答过这个问题几次了,但我仍然有点困惑所需的行为。当AppBar完全展开时,选项卡是否应该可见,还是当AppBar完全折叠时?并且当它们出现时,您希望选项卡在哪里? - PPartisan
@PPartisan 让我一步一步地告诉你。最初,带有图像的折叠工具栏是完全展开的,选项卡可见。然后,当向下滚动时,折叠工具栏图像将缩小到工具栏中(选项卡仍可见)。当折叠工具栏完全折叠时,进一步向下滚动将隐藏选项卡,但固定工具栏。向上滚动将再次显示选项卡。 - syloc
显示剩余2条评论
5个回答

20

嗨,这个或许可以解决你的问题。

只需将android:layout_gravity="bottom"添加到选项卡布局中,将android:gravity="top"添加到工具栏中。

输入图片描述


实际上,这是关于工具栏底部边距的问题。 - Jacek Kwiecień
示例链接中的示例非常好,与此图像完全相同。 - Vasile Doe
5
该链接已过时。 - Leo DroidCoder
@Jimale,你提供的链接是垃圾链接,请删除此链接,否则我将投诉你,你正在传播垃圾信息。 - pavel
@Pavel 这不是我的答案,我已经编辑过了。 - Jimale Abdi

5
  1. android.support.design.widget.TabLayout中删除属性app:layout_behavior="@string/appbar_scrolling_view_behavior"app:layout_scrollFlags="scroll|enterAlways",并添加属性android:layout_gravity="bottom"

  2. 同时将android.support.v7.widget.Toolbar的高度设置为104(Toolbar+TabLayout高度),以在收缩状态下显示ToolbarTabLayout

以下是一个可行的示例:

<?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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:titleEnabled="false">

            <ImageView
                android:id="@+id/image_header"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/anim_toolbar"
                android:layout_width="match_parent"
                android:layout_height="104dp"
                android:minHeight="?attr/actionBarSize"
                android:gravity="top"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:titleMarginTop="13dp" />


            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                app:tabGravity="fill"
                app:tabMode="scrollable"
                style="@style/MyCustomTabLayout"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        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_map"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        app:backgroundTint="#f44336"
        android:src="@drawable/ic_maps_my_location" />

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

希望这能对你有所帮助~

3

我有些不清楚这里需要实现什么。

  1. 如果你想要TAB在滚动时不上下移动,那么你需要将TabLayout放在CollapsingToolbarLayout之外。因为任何放在CollapsingToolbarLayout中的内容都会随着滚动而移动。

根据你的评论,我修改了你的xml文件,模仿了YouTube屏幕的样式。由于工具栏是固定的且不受滚动影响,所以将其放在协调布局外面是值得一提的事情。有一点需要注意的是:"一个注释:使用滚动标志的所有视图必须在不使用标志的视图之前声明。这确保了所有视图从顶部退出,而将固定元素留在后面。" 这是从安卓博客文章中引用的http://android-developers.blogspot.in/2015/05/android-design-support-library.html。这就是为什么我将工具栏移出AppBarLayout的原因。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"/>

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/main_content"
        android:layout_below="@id/toolbar"
        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.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_scrollFlags="scroll|enterAlways"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

        </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.CoordinatorLayout>

</RelativeLayout>

我已经将TabLayout设置为静态,但你可以使其可滚动。如果这不是你要实现的内容,请用图片解释一下。我很乐意帮忙。

我想要一个类似于Youtube应用程序的布局。您可以在那里检查选项卡的行为。还有一个要求是,我想在工具栏内放置一张图片。 - syloc
我正在查看YouTube应用程序的MainScreen。 工具栏固定高度为56dp,TabLayout也是如此。 在滚动视频列表时,它们都没有任何变化。这里根本没有使用CollapsingToolbarLayout。 再回到YouTube应用程序,工具栏从不改变高度(从不展开),因此在那里放置图像没有意义。 但是,如果要在Collapsing ToolbarLayout中使用图像,则可以参考'CheeseDetailActivity.java'及其对应的xml布局'activity_detail.xml'。 - Henry
不是主屏幕。打开某个用户的详细信息屏幕。您可以在那里看到选项卡(主页、视频、播放列表...)。 - syloc
明白了。我已经更新了我的答案。它模仿了你所说的YouTube屏幕。工具栏被固定,TabLayout在滚动时上下移动。 - Henry
如我上面所评论的; 我需要在工具栏内部放置一张图像。因此,我需要一个可折叠的工具栏布局。 - syloc
@syloc找到解决方案了吗? - Vaclovas Rekašius Jr.

1

我使用视差效果构建了两个示例,以及一个在AppbarLayout上使用RecyclerView的示例。

其中一个只有视差效果。

enter image description here

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/htab_maincontent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <!--
    OUTLINE
    <CoordinatorLayout>
        <AppbarLayout>
               <CollapsingToolbarLayout>
                    <ImageView/>
                 <Toolbar/>
                 <TabLayout/>
            </CollapsingToolbarLayout>
        </ AppbarLayout >
        <NestedScrollView/>
    </CoordinatorLayout>
    -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/ivHeader"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@android:color/transparent"
                app:tabIconTint="#F57C00"
                app:tabIndicatorColor="#F57C00"
                app:tabIndicatorHeight="4dp"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="#F5F5F5"
                app:tabTextColor="#FFE0B2" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

而位于 AppbarLayout 上方的是 RecyclerView。

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/htab_maincontent"
    android:layout_width="match_parent"
    android:background="#EEEEEE"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <!--
    OUTLINE
    <CoordinatorLayout>
        <AppbarLayout>
               <CollapsingToolbarLayout>
                    <ImageView/>
                 <Toolbar/>
                 <TabLayout/>
            </CollapsingToolbarLayout>
        </ AppbarLayout >
        <NestedScrollView/>
    </CoordinatorLayout>
    -->
    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="330dp"
            android:fitsSystemWindows="true"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/ivHeader"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/header"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                android:layout_gravity="top"
                android:layout_marginBottom="?attr/actionBarSize" />

            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                android:background="@android:color/transparent"
                app:tabIconTint="#F57C00"
                app:tabIndicatorColor="#F57C00"
                android:translationY="-30dp"
                app:tabIndicatorHeight="4dp"
                app:tabMode="scrollable"
                app:tabSelectedTextColor="#F5F5F5"
                app:tabTextColor="#FFE0B2" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/constraintLayout"
        app:behavior_overlapTop="30dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager2"
            android:layout_width="match_parent"
            android:background="#fff"
            android:layout_marginStart="10dp"
            android:layout_marginEnd="10dp"
            android:layout_height="match_parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

在滚动时设置TabLayouttranslationY

,并保留HTML标签。
// Check if scrolling up or down
   var initTransitionY = tabLayout.translationY
    tabLayout.post {
        initTransitionY = tabLayout.translationY
    }

appbar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->

    //Check if the view is collapsed
    if (abs(verticalOffset) >= appbar.totalScrollRange) {
        collapsingToolbar.title = "Collapsed"
    } else {
        collapsingToolbar.title = ""
    }

        tabLayout.translationY =
            initTransitionY + initTransitionY * (verticalOffset / appBarLayout.totalScrollRange.toFloat())

})

您可以查看this repo以获取完整示例和其他示例。


0
将 android.support.design.widget.TabLayout 中添加 android:layout_gravity="bottom"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接