【问题标题】:Stop CollapsingToolbar from collapsing after NestedScrollView runs out of content to scroll在 NestedScrollView 用完滚动内容后停止 CollapsingToolbar 折叠
【发布时间】:2015-09-16 00:35:09
【问题描述】:

在 Android 中,如果 NestedScrollView 的滚动内容不足,如何让 CollapsingToolbar 停止折叠?此功能目前存在于 Android 5.1.1 上的联系人应用程序中。但是,在我的代码中,当 NestedScrollView 停止滚动时,工具栏会继续折叠,从而在两者之间留下空隙。

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    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="256dp"
        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="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="@dimen/content_padding_normal"
            app:expandedTitleMarginEnd="64dp">
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:titleTextAppearance="@style/ActionBar.TitleText"
                app:layout_collapseMode="pin" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>
    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:scrollbars="none">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingBottom="@dimen/keyline_2">
            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/element_spacing_normal">
                <include
                    layout="@layout/ViewLoadingIndeterminate" />
                <LinearLayout
                    android:id="@+id/progress_status_container"
                    style="@style/ConnectionFieldContainer"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:orientation="vertical"
                    android:visibility="visible">
                    <Spinner
                        android:id="@+id/progress_status"
                        android:layout_width="match_parent"
                        style="@style/Text.ConnectionField" />
                    <TextView
                        style="@style/Text.ConnectionLabel"
                        android:text="@string/mobile.customer.connect.progress.status" />
                </LinearLayout>
            </android.support.v7.widget.CardView>
            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/element_spacing_normal">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
                    <LinearLayout
                        android:id="@+id/email1_container"
                        style="@style/ConnectionFieldContainer"
                        android:orientation="horizontal"
                        tools:visibility="visible">
                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:layout_weight="1"
                            android:orientation="vertical">
                            <TextView
                                android:id="@+id/email1"
                                style="@style/Text.ConnectionField"
                                tools:text="bgnosis@gmail.com" />
                            <TextView
                                style="@style/Text.ConnectionLabel"
                                android:text="@string/mobile.customer.connect.email1" />
                        </LinearLayout>
                        <ImageButton
                            android:id="@+id/action_email1"
                            style="@style/Button.ConnectionAction"
                            android:src="@drawable/ic_email_black_24dp" />
                    </LinearLayout>
                    <LinearLayout
                        android:id="@+id/email2_container"
                        style="@style/ConnectionFieldContainer"
                        android:orientation="horizontal"
                        tools:visibility="visible">
                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:layout_weight="1"
                            android:orientation="vertical">
                            <TextView
                                android:id="@+id/email2"
                                style="@style/Text.ConnectionField"
                                tools:text="alternate@email.com" />
                            <TextView
                                style="@style/Text.ConnectionLabel"
                                android:text="@string/mobile.customer.connect.email2" />
                        </LinearLayout>
                        <ImageButton
                            android:id="@+id/action_email2"
                            style="@style/Button.ConnectionAction"
                            android:src="@drawable/ic_email_black_24dp" />
                    </LinearLayout>
                    <LinearLayout
                        android:id="@+id/phone_day_container"
                        style="@style/ConnectionFieldContainer"
                        android:orientation="horizontal"
                        tools:visibility="visible">
                        <LinearLayout
                            android:layout_width="0dp"
                            android:layout_height="wrap_content"
                            android:layout_gravity="center_vertical"
                            android:layout_weight="1"
                            android:orientation="vertical">
                            <TextView
                                android:id="@+id/phone_day"
                                style="@style/Text.ConnectionField"
                                tools:text="801-555-1234" />
                            <TextView
                                style="@style/Text.ConnectionLabel"
                                android:text="@string/mobile.customer.connect.phone.day" />
                        </LinearLayout>
                        <ImageButton
                            android:id="@+id/action_call_phone_day"
                            style="@style/Button.ConnectionAction"
                            android:src="@drawable/ic_call_black_24dp" />
                        <ImageButton
                            android:id="@+id/action_text_phone_day"
                            style="@style/Button.ConnectionAction"
                            android:src="@drawable/ic_textsms_black_24dp" />
                    </LinearLayout>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/create_reminder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/collapsing_toolbar"
        app:layout_anchorGravity="bottom|right|end"
        app:borderWidth="0dp"
        app:elevation="@dimen/shadow_size"
        android:layout_marginBottom="@dimen/keyline_1"
        android:layout_marginRight="@dimen/keyline_1"
        android:src="@drawable/ic_alarm_add_white_24dp"
        app:backgroundTint="?attr/colorAccent" />
</android.support.design.widget.CoordinatorLayout>

【问题讨论】:

  • 哥们,我也想知道答案...
  • 有人想出这个吗?

标签: android android-collapsingtoolbarlayout android-coordinatorlayout


【解决方案1】:

只需添加

android:layout_gravity="fill_vertical"

在您的 NestedScrollView 中。 :)

【讨论】:

  • 这个答案实际上并不能解决问题。它只是导致折叠的工具栏和内容一直折叠到顶部,在屏幕底部留下一个间隙。它看起来确实比在工具栏和内容之间有间隙更好,但实际上并没有解决问题。
  • CollapsingToolbar... 这只是浪费时间。在某些设备上,GUI 被切断了。
  • 如果用RecyclerView代替NestedScrollView,我们怎样才能达到同样的效果?
  • 谢谢哥们,很有帮助。
【解决方案2】:

今天我做了一个自定义行为,就是这样做的。

它扩展了 AppBarLayout.ScrollingViewBehavior,因此必须在您的滚动视图(NestedScrollView 或其他)上进行设置。

你可以找到它on Github,让我知道它是否有效。

关键部分是根据内容高度以编程方式设置 AppBarLayout 折叠高度,这样当它结束时,滚动停止。

【讨论】:

  • 这个和 DPanic284 的答案应该是正确的答案。他们的工作就像一个魅力。
  • 我用过这个,效果很好。但是有一个问题是,在我的布局中,我使用了许多编辑文本,这些文本必须设置动态文本,这会导致布局拉长。但是这种滚动行为无法重新测量布局更改。
【解决方案3】:

把你的NestedScrollView设为

 <android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:scrollbars="none">

CollapsingToolbarLayout 将折叠,NestedScrollView 内容将根据您的需要运行。

【讨论】:

    【解决方案4】:

    一个可能不适合的快速解决方案是,在活动创建中,测量屏幕高度并将作为 minimunHeight 分配给您的 nestedScrollView 子项。这不会阻止 Appbar 滚动,但您的内容会一直向上滚动。

     //Calculate screen height in pixels
     DisplayMetrics displaymetrics = new DisplayMetrics();
     getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
     mScreenHeight = displaymetrics.heightPixels;
    
     //Get Statusbar size
     int statusBatHeight = 0;
     int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
     if (resourceId > 0) {
          mStatusBarHeight = getResources().getDimensionPixelSize(resourceId);
     }
    
     mContainer = (FrameLayout) findViewById(R.id.fragment_container);
     mContainer.setMinimumHeight(mScreenHeight - mStatusBarHeight);
    

    另一种解决方案(不是快速解决方案)是扩展 NestedScrollView 并覆盖 dispatchNestedPreScroll()。该方法用于告诉 Coordinator Layout 您滚动了一定数量的像素。这个想法是计算您是否已经滚动了所有像素,然后调用 super.dispatchNestedScrollView() 或没有。

    要计算您是否已经显示了所有需要屏幕大小的内容,请遍历您的孩子以测量内容,以及您已经滚动了多少。

    事情变得有点复杂了。

    【讨论】:

      【解决方案5】:

      添加下一行

      android:layout_gravity="fill_vertical"
      

      到您的嵌套ScrollView

      【讨论】:

        【解决方案6】:

        我建议将natario's solution 与下面的代码一起使用,以避免在滚动时对 appBarLayout 造成干扰。

        app:scrimVisibleHeightTrigger="?attr/actionBarSize"

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-12-10
          • 2019-11-28
          • 2015-10-14
          • 1970-01-01
          • 2012-09-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多