如何让Android中的MotionLayout拖动向上时全屏展开?
问题:MotionLayout无法向上全屏展开,受内部内容高度限制
开发的Android应用中,通过向上拖动实现ImageView与底部LinearLayout的展开折叠动画,但当前MotionLayout的最大展开高度受内部视图(TextView/RecyclerView)内容高度限制,无法向上完全铺满屏幕,期望实现全屏展开效果。
相关代码
1. 起始布局(motion_layout_start)
<?xml version="1.0" encoding="utf-8"?> <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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" app:layoutDescription="@xml/activity_main_scene"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="0dp" android:scaleType="centerCrop" android:src="@drawable/download" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="150dp" android:background="@drawable/curvy_black_layout" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:fontFamily="sans-serif-condensed-medium" android:padding="20dp" android:scrollbars="vertical" android:text="@string/str" android:textColor="@color/black" android:textSize="18sp" /> </LinearLayout> </androidx.constraintlayout.motion.widget.MotionLayout>
2. 结束布局(motion_scene_end)
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="0dp" android:scaleType="centerCrop" android:src="@drawable/download" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:background="@drawable/curvy_black_layout" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="vertical" android:textSize="18sp" android:textColor="@color/black" android:fontFamily="sans-serif-condensed-medium" android:padding="20dp" android:text="@string/str"/> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
3. MotionScene布局描述文件
<?xml version="1.0" encoding="utf-8"?> <MotionScene xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <Transition app:constraintSetEnd="@layout/activity_main_motion_scene_end" app:constraintSetStart="@layout/activity_main_motion_scene_start" > <OnSwipe app:touchAnchorSide="top" app:onTouchUp="stop" app:autoCompleteMode="spring"/> </Transition> </MotionScene>
解决方案
问题核心是结束布局中LinearLayout的高度设为wrap_content,导致其高度被内部内容限制,无法向上拉伸至全屏。调整步骤如下:
1. 修改结束布局的LinearLayout约束与高度
将结束布局里的LinearLayout高度从wrap_content改为0dp,同时添加顶部约束到父布局顶部,让它可以占据从屏幕顶部到底部的全部空间:
<LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="0dp" android:orientation="vertical" android:background="@drawable/curvy_black_layout" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent">
2. 优化滑动触发逻辑(可选)
给OnSwipe添加dragDirection属性,明确向上滑动的触发方向,提升交互精准度:
<OnSwipe app:touchAnchorSide="top" app:onTouchUp="stop" app:autoCompleteMode="spring" app:dragDirection="dragUp"/>
3. 处理内部滚动视图(若为RecyclerView)
如果LinearLayout内部是RecyclerView,需给其设置android:fillViewport="true",确保内容不足时也能撑满LinearLayout空间:
<androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"/>
调整完成后,向上拖动时LinearLayout会完全铺满屏幕,ImageView会被推至屏幕外,实现预期的全屏展开效果。
内容的提问来源于stack exchange,提问作者Taki
相关产品推荐
相关产品推荐

