RecyclerView 在 MotionLayout 中跳转到其他视图

RecyclerView jumps on other views in MotionLayout

我在 Github 有一个项目:https://github.com/Ali-Rezaei/TMDb-Paging

我在其中使用 MotionLayout :

<data>

    <variable
        name="movie"
        type="com.sample.android.tmdb.vo.Movie" />

    <variable
        name="vm"
        type="com.sample.android.tmdb.ui.detail.MovieDetailViewModel" />
</data>

<android.support.constraint.motion.MotionLayout
    android:id="@+id/details_motion"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_show_details">

    <ImageView
        android:id="@+id/details_backdrop"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:imageUrl="@{movie.backdropPath}"
        tools:ignore="ContentDescription" />

    <View
        android:id="@+id/details_backdrop_scrim"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
        app:layout_constraintEnd_toEndOf="@id/details_backdrop"
        app:layout_constraintStart_toStartOf="@id/details_backdrop"
        app:layout_constraintTop_toTopOf="@id/details_backdrop" />

    <android.support.v7.widget.AppCompatImageView
        android:id="@+id/details_poster"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@drawable/placeholder"
        android:scaleType="centerCrop"
        android:transformPivotX="0px"
        android:transformPivotY="0px"
        android:transitionName="@string/view_name_header_image"
        app:imageUrl="@{movie.posterPath}" />

    <!-- Needed to fill a rounding error gap in MotionLayout. See https://issuetracker.google.com/112728689 -->
    <View
        android:id="@+id/details_gap_filler"
        android:layout_width="match_parent"
        android:layout_height="2px"
        android:background="@color/window_background"
        app:layout_constraintBottom_toTopOf="@id/details_rv"
        tools:ignore="PxUsage" />

    <com.sample.android.tmdb.widget.TopLeftCutoutBackgroundView
        android:id="@+id/details_appbar_background"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:backgroundColor="@color/window_background"
        app:topLeftCutSize="@dimen/details_corner_cutout" />

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/details_title"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:ellipsize="end"
        android:text="@{movie.title}"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:transitionName="@string/view_name_header_title" />

    <android.support.v7.widget.Toolbar
        android:id="@+id/details_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:theme="@style/Toolbar" />

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/details_rv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/window_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/details_appbar_background">

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding_normal"
                android:layout_marginTop="@dimen/padding_normal"
                android:layout_marginRight="@dimen/padding_normal"
                android:layout_marginBottom="@dimen/padding_micro"
                android:fontFamily="sans-serif-light"
                android:text="@{@string/release_date(movie.releaseDate)}"
                android:textAppearance="@style/TextAppearance.AppCompat.Small" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding_normal"
                android:layout_marginRight="@dimen/padding_normal"
                android:fontFamily="sans-serif-light"
                android:text="@{@string/rating(movie.voteAverage)}"
                android:textAppearance="@style/TextAppearance.AppCompat.Small" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding_normal"
                android:layout_marginTop="@dimen/padding_large"
                android:layout_marginRight="@dimen/padding_normal"
                android:text="@string/summary"
                android:textAppearance="@style/TextAppearance.AppCompat.Title" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/padding_normal"
                android:fontFamily="sans-serif-light"
                android:text="@{movie.overview}"
                android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

            <include
                layout="@layout/trailers"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding_normal"
                android:layout_marginTop="@dimen/padding_normal"
                android:layout_marginBottom="@dimen/padding_normal"
                app:vm="@{vm}"
                tools:ignore="RtlHardcoded" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="@dimen/padding_normal"
                android:layout_marginRight="@dimen/padding_normal"
                android:layout_marginBottom="12dp"
                android:text="@string/actors"
                android:textAppearance="@style/TextAppearance.AppCompat.Title"
                app:visibleGone="@{vm.isActorsVisible}" />

            <android.support.v7.widget.RecyclerView
                android:id="@+id/actors"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:items="@{vm.casts}"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        </LinearLayout>

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


    <!-- This needs to be updated to use WindowInsets. See https://issuetracker.google.com/issues/112605433 -->
    <View
        android:id="@+id/details_status_bar_anchor"
        android:layout_width="match_parent"
        android:layout_height="24dp"
        android:background="@color/status_bar_scrim_translucent_dark" />

</android.support.constraint.motion.MotionLayout>

有时 RecyclerView(with id actor) 会跳转到 NestedScrollView 中的其他视图。

您可以在没有 RecyclerView 的情况下查看正确的行为:https://github.com/Ali-Rezaei/TMDb-Paging/tree/master

当 NestedScrollView 中的其他视图高度较短时,会发生这种情况。 你知道为什么会这样吗?

我试过了:

<android.support.v4.widget.NestedScrollView
            android:id="@+id/details_rv"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/window_background"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent">

...

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

        <android.support.v7.widget.RecyclerView
            android:id="@+id/details_cast"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:items="@{vm.cast}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/details_rv" />

但在 RecyclerView 中不显示转换。

这是scene_show_details:

<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@id/start"
        app:duration="200">

        <OnSwipe
            app:dragDirection="dragUp"
            app:moveWhenScrollAtTop="true"
            app:touchAnchorId="@id/details_rv"
            app:touchAnchorSide="top" />

        <KeyFrameSet>
            <KeyPosition
                app:framePosition="20"
                app:keyPositionType="deltaRelative"
                app:percentY="0.51"
                app:target="@id/details_poster" />

            <!-- This looks weird. We need a quick change from elevated to not-so-elevated at 20% so we set 2 key
                 attributes, one at 20% and other at 25%. -->
            <KeyAttribute
                android:elevation="@dimen/z_app_bar"
                android:rotation="45"
                android:rotationY="15"
                app:framePosition="20"
                app:target="@id/details_poster" />

            <KeyAttribute
                android:elevation="@dimen/details_poster_not_elevation"
                app:framePosition="25"
                app:target="@id/details_poster" />

            <!-- Only elevate the appbar background over the last 25% -->
            <KeyAttribute
                android:elevation="0dp"
                app:framePosition="75"
                app:target="@id/details_appbar_background" />

        </KeyFrameSet>

    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/details_backdrop"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@id/details_backdrop_scrim"
            app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
            app:layout_constraintEnd_toEndOf="@id/details_backdrop"
            app:layout_constraintStart_toStartOf="@id/details_backdrop"
            app:layout_constraintTop_toTopOf="@id/details_backdrop">

            <CustomAttribute
                app:attributeName="background"
                app:customColorDrawableValue="@android:color/transparent" />

        </Constraint>

        <Constraint
            android:id="@id/details_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="0dp"
            app:layout_constraintTop_toBottomOf="@id/details_status_bar_anchor">

            <CustomAttribute
                app:attributeName="iconTint"
                app:customColorValue="?android:attr/textColorPrimaryInverse" />

        </Constraint>

        <Constraint
            android:id="@id/details_appbar_background"
            android:layout_width="0dp"
            android:layout_height="88dp"
            app:layout_constraintBottom_toBottomOf="@id/details_poster"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />

        <Constraint
            android:id="@id/details_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="24dp"
            app:layout_constraintBottom_toTopOf="@id/details_appbar_background"
            app:layout_constraintEnd_toEndOf="@id/details_appbar_background"
            app:layout_constraintStart_toEndOf="@id/details_poster"
            app:layout_constraintTop_toBottomOf="@id/details_appbar_background" />

        <Constraint
            android:id="@id/details_poster"
            android:layout_width="80dp"
            android:layout_height="0dp"
            android:layout_marginStart="@dimen/padding_normal"
            android:layout_marginTop="200dp"
            android:elevation="@dimen/z_app_bar"
            app:layout_constraintDimensionRatio="h,1:1.5"
            app:layout_constraintStart_toStartOf="@id/details_rv"
            app:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/details_backdrop"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@id/details_backdrop_scrim"
            app:layout_constraintBottom_toBottomOf="@id/details_backdrop"
            app:layout_constraintEnd_toEndOf="@id/details_backdrop"
            app:layout_constraintStart_toStartOf="@id/details_backdrop"
            app:layout_constraintTop_toTopOf="@id/details_backdrop">

            <CustomAttribute
                app:attributeName="background"
                app:customColorDrawableValue="@color/status_bar_scrim_translucent_dark" />

        </Constraint>

        <Constraint
            android:id="@id/details_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:elevation="@dimen/z_app_bar"
            app:layout_constraintTop_toBottomOf="@id/details_status_bar_anchor">

            <CustomAttribute
                app:attributeName="iconTint"
                app:customColorValue="?android:attr/textColorPrimary" />

        </Constraint>

        <Constraint
            android:id="@id/details_appbar_background"
            android:layout_width="0dp"
            android:layout_height="?android:attr/actionBarSize"
            android:elevation="@dimen/z_app_bar"
            app:layout_constraintEnd_toEndOf="@id/details_rv"
            app:layout_constraintStart_toStartOf="@id/details_rv"
            app:layout_constraintTop_toBottomOf="@id/details_status_bar_anchor" />

        <Constraint
            android:id="@id/details_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="48dp"
            android:layout_marginStart="64dp"
            android:elevation="@dimen/z_app_bar"
            app:layout_constraintBottom_toBottomOf="@id/details_appbar_background"
            app:layout_constraintEnd_toEndOf="@id/details_appbar_background"
            app:layout_constraintStart_toStartOf="@id/details_appbar_background"
            app:layout_constraintTop_toTopOf="@id/details_appbar_background" />

        <Constraint
            android:id="@id/details_poster"
            android:layout_width="72dp"
            android:layout_height="0dp"
            android:elevation="@dimen/details_poster_not_elevation"
            app:layout_constraintDimensionRatio="h,1:1.5"
            app:layout_constraintStart_toStartOf="@id/details_title"
            app:layout_constraintTop_toBottomOf="@id/details_status_bar_anchor" />

    </ConstraintSet>


</MotionScene>

可以在以下位置找到问题跟踪:https://issuetracker.google.com/issues/121439694