OnSwipe dragUp 不适用于 MotionLayout 中的 View with child

OnSwipe dragUp doesn't work on View with child in MotionLayout

我想使用 MotionLayout 在我的 activity 中实现底部 Sheet。

动态场景:

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

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="2000">

        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@id/bottomSheet"
            motion:touchRegionId="@id/bottomSheet" />

    </Transition>

    <ConstraintSet android:id="@+id/start">

        <Constraint
            android:id="@+id/bottomSheet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            motion:layout_constraintBottom_toBottomOf="parent"/>

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">

        <Constraint
            android:id="@+id/bottomSheet"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            motion:layout_constraintTop_toTopOf="parent"
            motion:layout_constraintBottom_toBottomOf="parent"/>
    
    </ConstraintSet>

</MotionScene>

现在,如果我像下面的代码那样实现我的 MotionLayout,我就不能在按钮区域中向上拖动:

<androidx.constraintlayout.motion.widget.MotionLayout 
    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/ml"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    app:layoutDescription="@xml/activity_main_scene"
    tools:context=".MainActivity">

    <com.google.android.material.card.MaterialCardView
        android:id="@+id/bottomSheet"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardBackgroundColor="@android:color/black">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_red_dark"
            android:padding="40dp">

            <Button
                android:id="@+id/btn"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:text="A button" />

        </FrameLayout>

    </com.google.android.material.card.MaterialCardView>

</androidx.constraintlayout.motion.widget.MotionLayout>

我可以用 NestedScrollView 包装 MaterialCardView 然后因为 NestedScrollView 将正确处理 onInterceptTouchEvent,它会起作用:

<androidx.constraintlayout.motion.widget.MotionLayout 
    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/ml"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/darker_gray"
    app:layoutDescription="@xml/activity_main_scene"
    tools:context=".MainActivity">

    <androidx.core.widget.NestedScrollView
        android:id="@+id/bottomSheet"
        android:background="@android:color/holo_blue_dark"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.card.MaterialCardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardBackgroundColor="@android:color/black">

            <!-- other views -->

        </com.google.android.material.card.MaterialCardView>

    </androidx.core.widget.NestedScrollView>

</androidx.constraintlayout.motion.widget.MotionLayout>

如果我这样实现 MotionLayout,我将面临另一个问题。 MaterialCardView 高度在用户向上拖动视图时不会改变,即使我将高度设置为 match_parent:

如何更改代码,使红色区域覆盖整个蓝色区域?

终于,我找到了解决办法。我只需要添加

android:fillViewport="true"

到 NestedScrollView 以解决问题。发生这种情况是因为 NestedScrollView 的高度大于其最终状态下的子项,所以我需要将 fillViewport 设置为 true 来解决问题。