23

介绍

我有一个活动,它使用视差标题图像和滚动内容实现了一个通用模式CoordinatorLayoutAppBarLayoutCollapsingToolbarLayout。我的 xml 布局如下所示:

<android.support.design.widget.CoordinatorLayout
    android:fitsSystemWindows="true"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

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

        <android.support.design.widget.CollapsingToolbarLayout
            android:fitsSystemWindows="true"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <TextView
                android:background="@color/colorAccent"
                android:gravity="center"
                android:layout_height="250dp"
                android:layout_width="match_parent"
                android:text="ParallaxImage"
                app:layout_collapseMode="parallax"/>

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

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/content"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <TextView
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/text_margin"
            android:layout_width="wrap_content"
            android:text="@string/large_text"/>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

正如您在下面的 gif 动画中看到的那样,一切正常。NestedScrollView您可以从内容以及从Toolbar或 视差滚动整个屏幕View

AppBarLayout + NestedScrollView

问题

Google 引入了一个BottomSheetBehavior类(Android 设计支持库23.2)来帮助开发者实现底部表格。我的带有底页的 xml 布局如下所示:

<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: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/AppTheme.AppBarOverlay">
        <!-- ommited -->
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <!-- ommited -->
    </android.support.v4.widget.NestedScrollView>

    <LinearLayout
        android:id="@+id/bottomSheet"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="@android:color/holo_blue_bright"
        android:orientation="vertical"
        app:behavior_peekHeight="?attr/actionBarSize"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center_vertical"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:text="BottomSheetLayout"
            android:textColor="@android:color/white"/>

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/bottomSheetContent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollbars="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@android:color/holo_green_dark"
                android:padding="16dp"
                android:text="@string/large_text"
                android:textColor="@android:color/white"/>

        </android.support.v4.widget.NestedScrollView>
    </LinearLayout>

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

结果如下所示:

在此处输入图像描述

如您所见,如果我从 parallax 开始滚动,现在我无法滚动View。按预期从内容NestedScrollView和作品中滚动。Toolbar

问题

我如何管理滚动以从视差View中工作(与第一个 gif 动画中的方式相同)?似乎BottomSheetBehavior拦截了触摸事件并阻止了AppBarLayout (AppBarLayoutBehavior)处理滚动。但奇怪的是,从作品中滚动和Toolbar视差都是. ViewToolbarAppBarLayout

4

6 回答 6

1

我正在复制粘贴我正在使用的 XML。顺便说一句,它正在三星 Galaxy S3、华为 Mate 8 和 Moto 上运行,我还没有尝试过模拟器(我删除了所有商业内容,只是放置了虚拟小部件)。

<?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/coordinatorlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbarlayout"
    android:layout_width="match_parent"
    android:layout_height="256dp"
    android:theme="@style/AppTheme.AppBarOverlay"
    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/AppTheme.PopupOverlay"
            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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="16dp">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="16dp">

            <LinearLayout
                style="@style/Widget.CardContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo." />

            </LinearLayout>

        </android.support.v7.widget.CardView>

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp">

            <LinearLayout
                style="@style/Widget.CardContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="TITLE"
                android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="text 1" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="text 2" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="text 3" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="text 4" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="text 5" />

                </LinearLayout>

            </android.support.v7.widget.CardView>
        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>


<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:behavior_peekHeight="100dp"
    android:fitsSystemWindows="true"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="16dp"
        android:background="@android:color/white"
        android:padding="15dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="BOOTOMSHEET TITLE"
            android:textAppearance="@style/TextAppearance.AppCompat.Title" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Button1"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="text 2"
            android:layout_margin="10dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="text 3"
            android:layout_margin="10dp"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="text 4"
            android:layout_margin="10dp"/>


        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="320dp"
            android:background="@color/colorAccent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="Your remaining content here"
                android:textColor="@android:color/white" />

        </FrameLayout>
    </LinearLayout>
</android.support.v4.widget.NestedScrollView>

于 2016-05-19T20:41:28.413 回答
0

尝试这个

 <LinearLayout
        android:id="@+id/bottomSheet"
        android:layout_width="match_parent"
        android:layout_height="400dp">

将高度 400dp 更改为 wrap_content

希望对你有用

于 2016-05-09T11:11:12.783 回答
0

可以通过将 NestedScrollView(或在我的情况下包含 NestedScrollView 的片段)移动到FrameLayout 中的 CoordinatorLayout 之外并在 NestedScrollView 所在的位置放置一个虚拟视图来解决该问题,如下所示:

<FrameLayout>
    <CoordinatorLayout>
        <AppBarLayout>
            ...
        </AppBarLayout>
        <View
            android:id="@+id/bottomSheet"
            app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />
    </CoordinatorLayout>
    <NestedScrollView
        android:id="@+id/bottomSheetContent">
        ...
    </NestedScrollView>
</FrameLayout>

最后,BottomSheetCallback在滑动时翻译实际内容视图的虚拟视图添加一个:

@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
    bottomSheetContent.setTranslationY((1f - slideOffset) * bottomSheetContent.getHeight());
}

显然,这是防止 CoordinatorLayout 对任何触摸事件做出反应(和拦截)的唯一方法。#JustGoogle 事物

于 2016-07-18T13:16:28.447 回答
0

我想出了我自己的答案:

  • 添加app:layout_behavior="...AppBarLayoutCustomBehavior"到您的appBarLayout.

  • 创建该类并从AppBarLayout.Behavior

  • 覆盖onStartNestedScrollonNestedFling

  • 创建一个类似的标志scrollDenial,并将其添加到下面的两个方法中,然后调用 super (scrollDenial && super.onStartNestedScroll...)

  • 现在,您需要在每个 onStartNestedScroll 上更新您的拒绝条件。我做了这样的事情:

    https://gist.github.com/recoverrelax/8dd37b54910d70b5cd6a130a070c51e9

附言。抱歉,这是 Kotlin :p 应该不难理解。它解决了bottomSheet问题。

于 2016-11-23T13:21:12.850 回答
0

这似乎是代码中的一个错误BottomSheetBehavior,因为如果您尝试调试代码,CoordinatorLayout您会看到当您触摸视差View时,它将被确定为布局,BottomSheetBehavior而不是HeaderBehavior.

因此,我发现的快速解决方法是设置OnTouchListener始终返回 true 到您的视差视图:

View parallaxView = findViewById(R.id.parallax_view);
parallaxView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return true;
    }
});

当然,不要忘记将android:id="@+id/parallax_view"视差折叠模式设置为您的视图。

希望能帮助到你!

于 2016-05-08T18:18:56.140 回答
0

我认为您应该使用NestedScrollView,BottomSheetBehavior替换打击作为 bootemSheet!

<android.support.v4.widget.NestedScrollView
    android:id="@+id/bottomSheet"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    android:background="@android:color/holo_blue_bright"
    android:orientation="vertical"
    app:behavior_peekHeight="?attr/actionBarSize"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:gravity="center_vertical"
            android:paddingLeft="16dp"
            android:paddingRight="16dp"
            android:text="BottomSheetLayout"
            android:textColor="@android:color/white"/>

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

            <TextView
                android:layout_width="match_parent"
                android:layout_height="400dp"
                android:background="@android:color/holo_green_dark"
                android:padding="16dp"
                android:text="@string/large_text"
                android:textColor="@android:color/white"/>
        </ScrollView>
    </LinearLayout>

</android.support.v4.widget.NestedScrollView>

NestedScrollView可以知道如何与工具栏嵌套,而不是LinearLayout

希望帮忙!!

于 2016-05-01T15:34:39.027 回答