即使嵌套滚动视图中没有滚动内容,折叠工具栏布局也会滚动

Collapsing Toolbar Layout Scroll even when there is no scrolling content in Nested Scroll View

我在我的项目中使用折叠工具栏布局,其中我使用一个 NestedScrollView,其中我有多个卡片视图,其中内容不是静态的,而是在 onActivityResult 中变化。我已将 CollapsingToolbarLayout 的最小高度设置为 100dp。所以我观察到其中的几个问题:

  1. 在大手机上,内容会向上滚动到最小高度 100dp,在底部留下一个大空白 space,这不是我们想要的结果。它应该只在必要时向上滚动。必要条件是,当我在文本字段中获得大文本值时,它应该滚动,否则不会滚动。
  2. 我在其中使用了 Natario Solution,它可以动态计算 CollapsingToolbarLayout 的最小高度,但它会以某种方式工作,但它会消失 NestedScrollView 的滚动能力,如果我得到大的动态文本,这是不是想要的结果。

我的 layout.xml 文件是:-

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:clickable="true"
    android:id="@+id/topBlock"
    app:layout_constraintTop_toTopOf="parent"
    android:focusable="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:id="@+id/navigation"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            app:elevation="0dp"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:background="@null"
            android:minHeight="100dp">

            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:id="@+id/collapse_bar"
                android:layout_width="match_parent"
                android:layout_height="250dp"
                android:background="@android:color/holo_blue_light"

                android:minHeight="100dp"

                app:layout_collapseMode="parallax"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
                app:layout_scrollInterpolator="@android:anim/decelerate_interpolator">


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

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

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/camera"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:elevation="8dp"
            app:backgroundTint="@color/white"
            app:fabSize="normal"
            app:layout_anchor="@+id/nestedScrollView"
            app:layout_anchorGravity="top|center_horizontal"
            app:srcCompat="@drawable/ic_launcher_background" />

        <androidx.core.widget.NestedScrollView
            android:id="@+id/nestedScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white"
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent">

       

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_width="match_parent"
                    android:background="@color/white"
                    android:layout_height="wrap_content">

                    ////My Scrolling Content(Contains many edit texts so its size may vary)
                </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.core.widget.NestedScrollView>


    </androidx.coordinatorlayout.widget.CoordinatorLayout>


</androidx.constraintlayout.widget.ConstraintLayout>

我没有在 MyActivity.kt 文件中做任何事情。请帮我解决这个问题。在过去的 15 天里,我已经尝试了这个社区中几乎所有的解决方案,但仍然没有成功。谢谢!!

编辑:按照建议,我已经将问题更新为 NestedScrollView 作为直接子项,并发布了 Android Studio 预览的屏幕截图,其中它正在获取正在穿越预览的高度。它应该根据 content.If 我制作 NestedScrollView wrap_content 的高度然后它仍然在底部留空 space 。在后台我有相机 运行 所以我必须让它与父级匹配才能使封面全高。

首先,你有CoordinatorLayout就不需要ConstraintLayout了。另外正如用户在评论中提到的,NestedScrollView 应该是 CoordinatorLayout 的直接 child 而不是 ConstraintLayout。按照您的这种方式设计,某些行为可能无法按预期工作,实际上是错误的设计。

我已经进行了更改,这是您在预览中看到的内容:

更新布局:

<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/topBlock"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="0dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapse_bar"
            android:layout_width="match_parent"
            android:layout_height="250dp"
            android:background="@android:color/holo_blue_light"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:layout_scrollInterpolator="@android:anim/decelerate_interpolator">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/myToolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme"
                app:title="Your title" />

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

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

    <androidx.core.widget.NestedScrollView
        android:id="@+id/nestedScrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipToPadding="false"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="40dp"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp">

            <TextView
                android:id="@+id/title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="20dp"
                android:text="MyRandomText"
                android:textColor="@android:color/black"
                android:textSize="42sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toTopOf="@+id/view"
                app:layout_constraintCircleRadius="0dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <View
                android:id="@+id/view"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="20sp"
                android:background="@android:color/holo_blue_light"
                app:layout_constraintTop_toBottomOf="@id/title" />

        </androidx.constraintlayout.widget.ConstraintLayout>
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/camera"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:elevation="8dp"
        android:src="@mipmap/ic_launcher"
        app:backgroundTint="@color/white"
        app:fabSize="normal"
        app:layout_anchor="@+id/nestedScrollView"
        app:layout_anchorGravity="top|center_horizontal" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

P.S:还请记住NestedScrollView应该只有一个child,因为它是第一个child。

这样才是正确的做法,您不必使用 kotlin-java 代码来实现滚动或其他行为,您将能够使用标志和属性来实现这些行为,例如layout_scrollFlagsexitUntilCollapsed 等。

对于您的问题我没有特别的解决方案,但我强烈建议您使用 Motion Layout。我也在开发一个带有 'collapsing toolbar' 的应用程序,我想做一个视差效果,就像在 Spotify 中一样。使用 Coordinator Layout 和 Collapsing Toolbar 真的很困难,而且关于它的文档不是很广泛所以老实说我不知道​​我在做什么。

我在网上研究了其他方法,最后我发现了这个。 Motion Layout 可让您 调整动画 细节。我知道考虑将整个布局从 CoordinatorLayout 更改为 MotionLayout 似乎需要大量工作,但事实并非如此。如果有的话,它是有益的,因为 MotionLayout 从 ConstraintLayout 扩展而来,并且您可以为布局的每个视图设置动画(如果您的父级是 MotionLayout)。另一个支持 ML 的论点是你有动画监听器:例如,当一个转换完成时,一个方法被自动调用,这样你就可以在需要时链接动画,这真的很有趣。

  1. 查看可以使用 Motion Layout 构建的一些可能的动画。它们带有布局 xml 和动画 xml,因此您可以从中学习(很棒的官方文档 btw): https://developer.android.com/training/constraint-layout/motionlayout/examples

  2. 这是我用来模仿协调器布局中折叠工具栏行为的教程: https://blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-1/ https://blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-2/ (我个人刚刚完成了第 1 部分,然后自己继续)