带有 NestedScrollView 的 CoordinatorLayout 为粘性按钮添加填充底部不起作用

Posted

技术标签:

【中文标题】带有 NestedScrollView 的 CoordinatorLayout 为粘性按钮添加填充底部不起作用【英文标题】:CoordinatorLayout with NestedScrollView adding padding bottom for sticky button not working 【发布时间】:2022-01-23 20:14:33 【问题描述】:

我有这种情况:

我已经创建了这个

<style name="Title.Collapsed" parent="android:TextAppearance">
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textSize">18sp</item>
    </style>

    <style name="Title.Expanded" parent="android:TextAppearance">
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textSize">28sp</item>
    </style>

这是我的布局

<?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:layout_
    android:layout_>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarLayout"
        android:layout_
        android:layout_
        android:background="@android:color/transparent"
        android:fitsSystemWindows="true"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbar"
            android:layout_
            android:layout_
            android:fitsSystemWindows="true"
            app:collapsedTitleGravity="end"
            app:collapsedTitleTextAppearance="@style/Title.Collapsed"
            app:expandedTitleGravity="end"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleTextAppearance="@style/Title.Expanded"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <LinearLayout
                android:layout_
                android:layout_
                android:layout_marginTop="40dp"
                android:background="@android:color/transparent"
                android:gravity="end"
                android:orientation="vertical"
                android:padding="10dp"
                app:layout_collapseMode="parallax">

                <TextView
                    android:id="@+id/tv_title"
                    android:layout_
                    android:layout_
                    android:text="Hi"
                    android:textSize="28sp" />
            </LinearLayout>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_
                android:layout_
                android:background="@color/design_default_color_primary"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

    <androidx.core.widget.NestedScrollView
        android:layout_
        android:layout_
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/appBarlayout">

        <TextView
            android:layout_
            android:layout_
            android:text="@string/long_text" />

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

然后我将折叠动画制作为:

val collapsingToolbar = findViewById<CollapsingToolbarLayout>(R.id.collapsingToolbar)
collapsingToolbar.title = ""
title = ""

val appBarLayout = findViewById<AppBarLayout>(R.id.appBarLayout)
appBarLayout.addOnOffsetChangedListener(object : OnOffsetChangedListener 
    var isShow = false
    var scrollRange = -1
    override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) 
        if (scrollRange == -1) 
            scrollRange = appBarLayout.totalScrollRange
        
        if (scrollRange + verticalOffset == 0) 
            //when collapsingToolbar at that time display actionbar title
            collapsingToolbar.title = "Hi"
            isShow = true
         else if (isShow) 
            collapsingToolbar.title = ""
            isShow = false
        
    
)

它完美无缺,现在的问题是我想添加一个粘性按钮,但我无法告诉 NestedScrollView 与我的按钮的底部对齐,因为它不在 ConstraintLayout 内,也不是它的子级,所以它没有在编译方面崩溃,但按钮隐藏了 scrollView 的最后一部分......我尝试添加 marginBottom="buttonSize" 并且在布局设计中它看起来不错,但是在编译时它不会做折叠动画,因为我'我添加了marginBottom。我怎样才能解决这个问题?我需要这个 NestedScrollView 不是高度 match_parent 即使它是 wrap_content 它与父级对齐并且按钮重叠。

【问题讨论】:

【参考方案1】:

您可以将CoordinatorLayout 和底部Button 包装在ConstraintLayout 中作为根布局;现在CoordinatorLayout 可以被限制在按钮的顶部,而不是具有等于整个屏幕高度的高度。

所以,布局将是:

<ConstraintLayout>

    <CoordinatorLayout>
        <AppBarLayout>
            <CollapsingToolbarLayout>
        <NestedScrollView>
    </CoordinatorLayout>
    
    <Button/>
    
</ConstraintLayout>

应用于您的布局:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_
        android:layout_
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintTop_toTopOf="parent">
            
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_
            android:layout_
            android:background="@android:color/transparent"
            android:fitsSystemWindows="true"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:id="@+id/collapsingToolbar"
                android:layout_
                android:layout_
                android:fitsSystemWindows="true"
                app:collapsedTitleGravity="end"
                app:collapsedTitleTextAppearance="@style/Title.Collapsed"
                app:expandedTitleGravity="end"
                app:expandedTitleMarginEnd="64dp"
                app:expandedTitleMarginStart="48dp"
                app:expandedTitleTextAppearance="@style/Title.Expanded"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

                <LinearLayout
                    android:layout_
                    android:layout_
                    android:layout_marginTop="40dp"
                    android:background="@android:color/transparent"
                    android:gravity="end"
                    android:orientation="vertical"
                    android:padding="10dp"
                    app:layout_collapseMode="parallax">

                    <TextView
                        android:id="@+id/tv_title"
                        android:layout_
                        android:layout_
                        android:text="Hi"
                        android:textSize="28sp" />
                </LinearLayout>

                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_
                    android:layout_
                    android:background="@color/design_default_color_primary"
                    app:layout_collapseMode="pin"
                    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

        <androidx.core.widget.NestedScrollView
            android:layout_
            android:layout_
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <TextView
                android:layout_
                android:layout_
                android:text="@string/long_text" />

        </androidx.core.widget.NestedScrollView>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>


    <Button
        android:id="@+id/button"
        android:layout_
        android:layout_
        android:layout_gravity="bottom"
        android:insetLeft="0dp"
        android:text="OK"
        android:insetTop="0dp"
        android:insetRight="0dp"
        android:insetBottom="0dp"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

以上是关于带有 NestedScrollView 的 CoordinatorLayout 为粘性按钮添加填充底部不起作用的主要内容,如果未能解决你的问题,请参考以下文章

当尝试从带有点击事件的视图滚动时,滚动在 NestedScrollView 中不起作用

带有 NestedScrollView 的 CoordinatorLayout 为粘性按钮添加填充底部不起作用

当在nestedscrollview的recyclerview中将项目拖出可见空间时-nestedscrollView不滚动

如果在 nestedScrollView 内,RecyclerView 不回收

NestedScrollView 和 Horizo​​ntal RecyclerView 平滑滚动

内容更改时,NestedScrollView 在顶部滚动