Макет координатора + странный эффект дрожания видового экрана - PullRequest
0 голосов
/ 09 ноября 2018

Базовая компоновка координатора, вызывающая эффект дрожания при броске (как показано на видео)

Этот эффект, по-видимому, имеет место только на Huawei (или на младших устройствах в целом). Тот же код отлично работает на Samsung s7 edge (и вообще на устройствах высокого класса, таких как мой OP6)

Я пытался изменить флаги прокрутки, но тщетно. Я также попытался пойти по пути нестандартного поведения, однако для меня там нет направления. Как будто я не ясно определил проблему (или ошибку в библиотеке поддержки дизайна), чтобы обойти ее с помощью некоторого пользовательского поведения. Я зашел в какой-то тупик по этому поводу.

Вот эффект в движении:

enter image description here

Редактировать: добавление XML-кода

<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/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="false"
android:focusable="true">

<android.support.design.widget.AppBarLayout
    android:id="@+id/toolbarView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/toolbar_color"
    android:elevation="0dp"
    app:elevation="0dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent">

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:contentScrim="@color/transparent"
        app:expandedTitleGravity="top"
        app:layout_collapseMode="pin"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:statusBarScrim="@color/transparent"
        app:titleEnabled="false">


        <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="75dp"
            android:paddingBottom="0dp"
            app:layout_collapseMode="parallax"
            app:layout_scrollFlags="scroll">


            <TextView
                android:id="@+id/textViewRecipeName"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="18dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="8dp"
                android:fontFamily="@string/font_family_regular"
                android:textColor="@color/text_color_18"
                android:textSize="18sp"
                android:textStyle="bold"
                app:layout_constraintEnd_toStartOf="@+id/textViewRating"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:text="Greek salad filled filo cupsGreek salad filled filo cups" />

            <TextView
                android:id="@+id/textViewRecipeCuisines"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="16dp"
                android:ellipsize="end"
                android:fontFamily="@string/font_family_regular"
                android:maxLines="4"
                android:textColor="@color/text_color_19"
                android:textSize="12sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="@id/textViewRecipeName"
                app:layout_constraintTop_toBottomOf="@id/textViewRecipeName"
                tools:text="Salads - Appetizers" />

            <TextView
                android:id="@+id/textViewRating"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="0dp"
                android:layout_marginEnd="18dp"
                android:fontFamily="@string/font_family_medium"
                android:letterSpacing="-0.02"
                android:textColor="@color/text_color_18"
                android:textSize="18sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="@id/textViewRecipeName"
                tools:text="5.0" />

            <TextView
                android:id="@+id/textViewRatingLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="2dp"
                android:fontFamily="@string/font_family_regular"
                android:text="@string/home_text_rating"
                android:textColor="@color/text_grey"
                android:textSize="10sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="@id/textViewRating"
                app:layout_constraintStart_toStartOf="@id/textViewRating"
                app:layout_constraintTop_toBottomOf="@id/textViewRating" />

            <ImageView
                android:id="@+id/imageViewForRecipe"
                android:layout_width="0dp"
                android:layout_height="183dp"
                android:layout_marginStart="18dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="18dp"
                android:scaleType="centerCrop"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@id/textViewRecipeCuisines" />

            <ImageView
                android:id="@+id/imageViewPlayVideo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="@id/imageViewForRecipe"
                app:layout_constraintEnd_toEndOf="@id/imageViewForRecipe"
                app:layout_constraintStart_toStartOf="@id/imageViewForRecipe"
                app:layout_constraintTop_toTopOf="@id/imageViewForRecipe"
                app:srcCompat="@drawable/ic_play_video" />


            <TextView
                android:id="@+id/textViewPrepTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="9dp"
                android:layout_marginEnd="18dp"
                android:drawableStart="@drawable/ic_prep_time"
                android:drawablePadding="6dp"
                android:fontFamily="@string/font_family_regular"
                android:letterSpacing="0.01"
                android:lineSpacingExtra="12sp"
                android:textColor="@color/recipeDetailsColor"
                android:textSize="12sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toBottomOf="@id/imageViewForRecipe"
                tools:text="30 min" />

            <View
                android:id="@+id/divider1"
                android:layout_width="1dp"
                android:layout_height="8dp"
                android:layout_marginEnd="8dp"
                android:background="@color/dividerGreyColor"
                app:layout_constraintBottom_toBottomOf="@id/textViewPrepTime"
                app:layout_constraintEnd_toStartOf="@id/textViewPrepTime"
                app:layout_constraintTop_toTopOf="@id/textViewPrepTime" />

            <TextView
                android:id="@+id/textViewCookTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="9dp"
                android:layout_marginEnd="4dp"
                android:drawableStart="@drawable/ic_cook_time"
                android:drawablePadding="6dp"
                android:fontFamily="@string/font_family_regular"
                android:letterSpacing="0.01"
                android:lineSpacingExtra="12sp"
                android:textColor="@color/recipeDetailsColor"
                android:textSize="12sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="@id/divider1"
                app:layout_constraintEnd_toStartOf="@id/divider1"
                app:layout_constraintTop_toBottomOf="@id/imageViewForRecipe"
                tools:text="10 min" />

            <View
                android:id="@+id/divider2"
                android:layout_width="1dp"
                android:layout_height="8dp"
                android:layout_marginEnd="8dp"
                android:background="@color/dividerGreyColor"
                app:layout_constraintBottom_toBottomOf="@id/textViewPrepTime"
                app:layout_constraintEnd_toStartOf="@id/textViewCookTime"
                app:layout_constraintTop_toTopOf="@id/textViewPrepTime" />

            <TextView
                android:id="@+id/textViewCapacity"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="9dp"
                android:layout_marginEnd="4dp"
                android:drawableStart="@drawable/ic_serving"
                android:drawablePadding="6dp"
                android:fontFamily="@string/font_family_regular"
                android:letterSpacing="0.01"
                android:lineSpacingExtra="12sp"
                android:textColor="@color/recipeDetailsColor"
                android:textSize="12sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="@id/divider2"
                app:layout_constraintEnd_toStartOf="@id/divider2"
                app:layout_constraintTop_toBottomOf="@id/imageViewForRecipe"
                tools:text="12 pcs" />

            <TextView
                android:id="@+id/textViewAboutThisRecipeLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="36dp"
                android:fontFamily="@string/font_family_medium"
                android:letterSpacing="0.01"
                android:lineSpacingExtra="10sp"
                android:text="@string/about_this_recipe"
                android:textColor="@color/text_color_18"
                android:textSize="14sp"
                android:textStyle="normal"
                app:layout_constraintStart_toStartOf="@id/textViewRecipeName"
                app:layout_constraintTop_toBottomOf="@id/textViewCapacity" />


            <TextView
                android:id="@+id/textViewAboutRecipeValue"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="11dp"
                android:ellipsize="end"
                android:fontFamily="@string/font_family_regular"
                android:letterSpacing="0.02"
                android:lineSpacingExtra="10sp"
                android:textColor="@color/text_color_19"
                android:textSize="13sp"
                android:textStyle="normal"
                app:layout_constraintEnd_toEndOf="@id/textViewRatingLabel"
                app:layout_constraintStart_toStartOf="@id/textViewRecipeName"
                app:layout_constraintTop_toBottomOf="@id/textViewAboutThisRecipeLabel"
                tools:text="A tosty and filling russian main course, rich in flavor. this plate was invented by rubio safona back in the 1950s after he was in france during WWII" />


        </android.support.constraint.ConstraintLayout>

        <android.support.v7.widget.Toolbar
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            android:background="@color/white"
            android:gravity="center"
            app:layout_collapseMode="pin">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="35dp"
                android:layout_marginEnd="16dp"
                app:srcCompat="@drawable/ic_alwadi"
                tools:ignore="ContentDescription" />
        </android.support.v7.widget.Toolbar>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            android:background="@color/transparent"
            android:gravity="top"
            android:theme="@style/ToolbarStyle"
            app:layout_collapseMode="pin">

            <android.support.constraint.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="?actionBarSize"
                android:gravity="center_vertical">


                <ImageView
                    android:id="@+id/imageViewFavorite"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="16dp"
                    android:background="?selectableItemBackgroundBorderless"
                    android:clickable="true"
                    android:focusable="true"
                    android:src="@drawable/ic_heart"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="1.0"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <ImageView
                    android:id="@+id/imageViewShare"
                    android:layout_width="18dp"
                    android:layout_height="20dp"
                    android:layout_marginEnd="16dp"
                    android:background="?selectableItemBackgroundBorderless"
                    android:clickable="true"
                    android:focusable="true"
                    android:src="@drawable/ic_share"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/imageViewFavorite"
                    app:layout_constraintHorizontal_bias="1.0"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </android.support.constraint.ConstraintLayout>


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

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

    <TextView
        android:id="@+id/textViewNoMenuItems"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center|bottom"
        android:drawableTop="@drawable/group_13"
        android:drawablePadding="8dp"
        android:text="No Items found!"
        android:visibility="gone"
        tools:visibility="visible" />


    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayoutViewPager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_scrollFlags="enterAlways"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabMode="fixed"
        app:tabSelectedTextColor="@color/colorAccent"
        app:tabTextAppearance="@style/tabLayoutTextAppearance"
        app:tabTextColor="@color/tab_layout_normal_text_color" />

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

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


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/viewPagerIngredientsPrep"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@id/linearLayoutButtons"
            android:layout_marginTop="4dp" />


        <LinearLayout
            android:id="@+id/linearLayoutButtons"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="16dp"
            android:layout_marginTop="13dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="19dp"
            android:orientation="vertical">

            <android.support.design.button.MaterialButton
                android:id="@+id/buttonToggleFavorite"
                style="@style/Widget.MaterialComponents.Button.OutlinedButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/add_to_favorites"
                android:textAppearance="@style/ButtonTextAppearance" />

            <android.support.design.button.MaterialButton
                android:id="@+id/buttonRateThisRecipe"
                style="@style/Widget.MaterialComponents.Button"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="14dp"
                android:text="@string/rate_this_recipe_text"
                android:textAppearance="@style/ButtonTextAppearance" />
        </LinearLayout>
    </RelativeLayout>

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

1 Ответ

0 голосов
/ 10 августа 2019

Причина этого в том, что 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")
...