向下滚动时,CollapsingToolbarLayout闪烁

时间:2018-12-05 09:49:02

标签: android android-collapsingtoolbarlayout android-appbarlayout android-nestedscrollview

我有一个详细信息页面,其中包括CoordinatorLayout中的CollapsingToolbarLayout和NestedScrollView。当我从CollapsingToolbarLayout向上滚动并非常快速且立即从NestedScrollView向下滚动时,它闪烁并且无法为我提供平滑的滚动。这也发生在Cheesesquare演示应用程序中。但是,在Whatsapp个人资料页面中,不会发生。

以下视频可帮助您更好地理解: http://sendvid.com/4xsrya3w


这是我页面的布局:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragmentPdpCoordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:descendantFocusability="beforeDescendants"
    android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/fragmentPdpAppbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        app:layout_behavior="com.altayer.nisnass.ui.behaviour.NoBounceBehavior">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/fragmentPdpCollapsingToolbar"
            android:layout_width="match_parent"
            android:layout_height="@dimen/pdp_toolbar_layout_height"
            android:fitsSystemWindows="true"
            app:collapsedTitleTextAppearance="@style/PdpToolbarCollapsedTitleText"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginBottom="@dimen/component_margin_medium"
            app:expandedTitleMarginStart="@dimen/component_margin_medium"
            app:expandedTitleTextAppearance="@style/PdpToolbarExpandedTitleText"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:statusBarScrim="?attr/colorPrimary">

            <!--Do not change the id of this view to anything else it needs to be the same
            as the root ID of the included layout-->
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="@dimen/pdp_image_viewer_height"
                android:layout_gravity="center"
                app:layout_collapseMode="parallax">

                <com.altayer.nisnass.ui.views.imageviewer.ImageViewer
                    android:id="@+id/fragmentPdpImageViewer"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

                <com.altayer.nisnass.plp.badge.BadgeListView
                    android:id="@+id/fragmentPdpBadgeListView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="@dimen/pdp_badge_bottom_margin" />

            </RelativeLayout>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/fragmentPdpToolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:contentInsetEnd="@dimen/pdp_toolbar_title_margin_end"
                app:layout_collapseMode="pin">

                <com.altayer.nisnass.ui.views.NisnassImageView
                    android:id="@+id/fragmentPdpToolbarImageViewThumbnail"
                    android:layout_width="wrap_content"
                    android:layout_height="?attr/actionBarSize"
                    android:adjustViewBounds="true" />

            </androidx.appcompat.widget.Toolbar>

            <include
                layout="@layout/fragment_pdp_toolbar_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_collapseMode="pin" />

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

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

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

        <LinearLayout
            android:id="@+id/fragmentPdpLinearLayoutDescriptionHeader"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/white"
            android:orientation="vertical">

            <com.altayer.nisnass.pdp.pdpviews.descriptionheader.DescriptionHeader
                android:id="@+id/fragmentPdpDescriptionHeader"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <View
                style="@style/Separator.Horizontal"
                android:layout_marginBottom="@dimen/component_margin_small" />

            <com.altayer.nisnass.pdp.pdpviews.pdpcarousels.PdpCarousels
                android:id="@+id/fragmentPdpCarousels"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <Space
                android:layout_width="0dp"
                android:layout_height="@dimen/cta_button_layout_height" />
        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

    <!-- TODO: This is a workaround to apply elevation like in design -->
    <androidx.cardview.widget.CardView
        android:id="@+id/fragmentPdpButtonAddToBagCardView"
        style="@style/NisnassCTAButtonOverlay"
        android:layout_width="match_parent"
        android:layout_height="@dimen/cta_button_layout_height"
        android:layout_gravity="bottom"
        tools:visibility="gone">

        <com.altayer.nisnass.ui.views.NisnassButton
            android:id="@+id/fragmentPdpCardViewButtonAddToBag"
            style="@style/NisnassButton.CTA"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/cta_button_margin"
            android:text="@string/fragment_pdp_add_to_bag" />

    </androidx.cardview.widget.CardView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fragmentPdpFloatingActionButtonPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:scaleType="centerInside"
        android:visibility="gone"
        app:backgroundTint="@color/white"
        app:layout_anchor="@id/fragmentPdpAppbar"
        app:layout_anchorGravity="bottom|right|end"
        app:srcCompat="@drawable/ic_play"
        app:useCompatPadding="true" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/fragmentPdpFrameLayoutFABBag"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="@dimen/activity_general_vertical_margin"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:gravity="center"
        android:visibility="gone"
        tools:visibility="visible">

        <ProgressBar
            android:id="@+id/fragmentPdpProgressBarFabBag"
            style="?android:attr/progressBarStyleLarge"
            android:indeterminateTint="@color/black"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="@+id/fragmentPdpFABBag"
            app:layout_constraintEnd_toEndOf="@+id/fragmentPdpFABBag"
            app:layout_constraintStart_toStartOf="@+id/fragmentPdpFABBag"
            app:layout_constraintTop_toTopOf="@+id/fragmentPdpFABBag" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fragmentPdpFABBag"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="centerInside"
            android:tint="@color/white"
            app:fabSize="normal"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:srcCompat="@drawable/ic_fullfilled_bag"
            app:useCompatPadding="true" />

        <com.altayer.nisnass.ui.views.NisnassTextView
            android:id="@+id/fragmentPdpTextViewBagCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:elevation="12dp"
            android:focusableInTouchMode="false"
            android:gravity="center"
            android:includeFontPadding="false"
            android:paddingTop="@dimen/fragment_confirmation_bag_count_margin_top"
            android:textAppearance="@style/NisnassTextAppearance.Medium.Small"
            android:textColor="@color/black"
            app:layout_constraintBottom_toBottomOf="@id/fragmentPdpFABBag"
            app:layout_constraintEnd_toEndOf="@id/fragmentPdpFABBag"
            app:layout_constraintStart_toStartOf="@id/fragmentPdpFABBag"
            app:layout_constraintTop_toTopOf="@id/fragmentPdpFABBag"
            tools:text="10" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingBottom="@dimen/cta_button_layout_height"
        app:behavior_hideable="true"
        app:behavior_peekHeight="0dp"
        app:layout_behavior="com.altayer.nisnass.colorandsize.ColorAndSizeBottomSheetBehavior">

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

我正在使用:

'androidx.appcompat:appcompat:1.0.2'

'com.google.android.material:material:1.0.0'

1 个答案:

答案 0 :(得分:0)

其背后的原因是因为当我们开始AppBarLayout的任何其他视图时,CoordinatorLayout不会停止运行。解决方案非常简单:只要CoordinatorLayout的任何子视图开始掠过,我们就需要停止AppBarLayout的掠过(以下代码适用于androidx)

class CustomAppBarBehavior : AppBarLayout.Behavior() {

    private var overScroller: OverScroller? = null

    override fun onNestedPreFling(coordinatorLayout: CoordinatorLayout,
                                  child: AppBarLayout,
                                  target: View,
                                  velocityX: Float,
                                  velocityY: Float): Boolean {
        stopAppBarLayoutFling()
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
    }

    private fun stopAppBarLayoutFling() {
        if (overScroller == null) {
            val scrollerField = javaClass.superclass.superclass.superclass.getDeclaredField("scroller")
            scrollerField.isAccessible = true
            overScroller = scrollerField.get(this) as? OverScroller
        }
        overScroller?.forceFinished(true)
    }
}

在支持版本27中,通过反射查找滚动条有些不同:

val scrollerField = javaClass.superclass.superclass.getDeclaredField("mScroller")