ScrollView 内部子布局如何填充满屏幕

探讨了ScrollView在Android布局中如何正确设置以填满整个屏幕的问题,特别是在内容不足一屏时。通过调整mFillViewport属性和子布局高度,可以实现ScrollView始终占据整个屏幕空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ScrollView 包含一个ViewGroup, 在ViewGroup中填充内容,超过一屏就滚动。
但是发现一个问题,在内容不超过一屏的情况下,设置子内容高度为:match_parent ,并不能起到布满屏幕的作用。并且编辑器还提示子布局建议用
wrap_content.

布局代码如下:

 <ScrollView
        android:id="@+id/touch_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="@color/red">
            
            //具体内容控件
            .......
               </LinearLayout>
    </ScrollView>

效果如下图:
在这里插入图片描述

查看ScrollView 源码看到:mFillViewport 参数为false时直接子视图退出测量,只有设置为true时会进行下面的设置。子布局会填充为父布局(ScorllView的macth_parent)

 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        **//设置 mFillViewport**
        if (!mFillViewport) {
            return;
        }

        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.UNSPECIFIED) {
            return;
        }

        if (getChildCount() > 0) {
            final View child = getChildAt(0);
            final int widthPadding;
            final int heightPadding;
            final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
            final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (targetSdkVersion >= VERSION_CODES.M) {
                widthPadding = mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin;
                heightPadding = mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin;
            } else {
                widthPadding = mPaddingLeft + mPaddingRight;
                heightPadding = mPaddingTop + mPaddingBottom;
            }

            final int desiredHeight = getMeasuredHeight() - heightPadding;
            // 如果子 view 高度小于 父 view 高度,那么需要重新设定高度
            if (child.getMeasuredHeight() < desiredHeight) {
                final int childWidthMeasureSpec = getChildMeasureSpec(
                        widthMeasureSpec, widthPadding, lp.width);
                        // 这里生成 MeasureSpec 传入的是 父控件也就是(ScorllView的高度),并且用的是 MeasureSpec.EXACTLY 
                final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
                        desiredHeight, MeasureSpec.EXACTLY);
                child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
            }
        }
    }

所以修改后的xml布局如下:

<ScrollView
        android:id="@+id/touch_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true” >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:background="@color/red">
            
            //具体内容控件
            .......
               </LinearLayout>
    </ScrollView>

效果如下
在这里插入图片描述
**

备注:这样处理的话,如果包裹的子布局内容不满一屏的情况下,布局也还是会占满整个屏幕。对于一些特殊情况可能要特殊处理

**

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值