MotionLayout中OnSwipe dragUp带子View失效及高度适配问题
问题核心原因
- 初始版本按钮区域无法触发滑动:可点击控件
Button默认消费触摸事件,导致MotionLayout的OnSwipe监听无法收到滑动事件 - 嵌套
NestedScrollView后红色区域无法填满蓝色区域:滚动容器默认不允许子View填充满自身可视区域,即便子View设置match_parent也不会生效
解决方案
只需两步修改即可解决问题:
- 给
NestedScrollView添加android:fillViewport="true"属性,允许子View填充滚动容器的可视区域 - 将
NestedScrollView内部的MaterialCardView、红色FrameLayout的高度设置为match_parent
修改后的布局代码
<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" <!-- 新增fillViewport属性 --> android:fillViewport="true"> <com.google.android.material.card.MaterialCardView android:layout_width="match_parent" <!-- 高度改为match_parent --> android:layout_height="match_parent" app:cardBackgroundColor="@android:color/black"> <FrameLayout android:layout_width="match_parent" <!-- 高度改为match_parent --> android:layout_height="match_parent" 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.core.widget.NestedScrollView> </androidx.constraintlayout.motion.widget.MotionLayout>
可选优化
如果需要滑动联动更顺畅,可以在MotionScene的OnSwipe节点添加属性:
motion:nestedScrollFlags="supportScroll"
原理解释
android:fillViewport是滚动容器的专属属性,默认值为false,此时子View高度最高只能等于自身内容高度,即使设置match_parent也不会填充滚动容器的空白区域;设置为true后,子View高度会自动适配滚动容器的当前可视高度,当NestedScrollView在MotionLayout的end状态下拉伸到满屏时,内部的Card和红色布局就会同步填满整个蓝色区域。
内容的提问来源于stack exchange,提问作者Ramin Abdolmaleki
相关产品推荐
相关产品推荐

