You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 06:17:04