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

Kivy ScrollView嵌套GridLayout时Label顶部被截断问题求解

GridLayout嵌套ScrollView时Label顶部被截断问题

问题现象

开发Kivy/KivyMD应用时,搭配使用GridLayout与ScrollView出现布局异常:ScrollView内部GridLayout承载的Label上半部分内容被截断,运行效果如下:
运行效果截图
对应异常代码隶属于BottomNavigation模块,.kv文件源码如下:

MDBottomNavigationItem:
    id: hmNav
    name: 'home'
    text: 'Home'
    icon: 'home'
    GridLayout:
        id: hmGrid
        cols: 1
        rows_minimum: {0: (self.parent.height) * 0.05, 1: (self.parent.height) * 0.2, 2: (self.parent.height) * 0.4, 3: (self.parent.height) * 0.1, 4: (self.parent.height) * 0.1}
        row_force_default: True
        MDLabel:
            id: welcomeLabel
            halign: 'center'
            font_name: "DMSans"
            text: "Hello, " + app.app.getId() + "!"
            theme_text_color: "Custom"
            font_size: '25sp'
            size: self.texture_size
            text_color: get_color_from_hex("#08421e")

        MDLabel:
            id: wLabel2
            halign: 'center'
            font_name: "DMSans"
            text: "Here are your selected ingredients:"
            theme_text_color: "Custom"
            font_size: '15sp'
            size: self.texture_size
            text_color: get_color_from_hex("#08421e")

        ScrollView:
            id: selectedScroll
            size: (self.parent.width, self.parent.height)
            do_scroll_x: False
            do_scroll_y: True
            bar_width: 20

            GridLayout:
                id: selectedGrid
                size_hint_y: None
                spacing: 60
                cols: 2
                height: self.minimum_height
                MDLabel:
                    halign: 'center'
                    text: "TEST1"
                    font_size: '15sp'
                    theme_text_color: "Custom"
                    text_color: get_color_from_hex("#08421e")
                    size: self.texture_size
                MDLabel:
                    halign: 'center'
                    text: "TEST2"
                    font_size: '15sp'
                    size: self.texture_size
                MDLabel:
                    halign: 'center'
                    text: "TEST1"
                    font_size: '15sp'
                    theme_text_color: "Custom"
                    text_color: get_color_from_hex("#08421e")
                    size: self.texture_size
                MDLabel:
                    halign: 'center'
                    text: "TEST2"
                    font_size: '15sp'
                    size: self.texture_size
                MDLabel:
                    halign: 'center'
                    text: "TEST1"
                    font_size: '15sp'
                    theme_text_color: "Custom"
                    text_color: get_color_from_hex("#08421e")
                    size: self.texture_size
                MDLabel:
                    halign: 'center'
                    text: "TEST2"
                    font_size: '15sp'
                    size: self.texture_size

        MDLabel:
            halign: 'center'
            text: "TEST 3"
            font_size: '15sp'
            size: self.texture_size

        MDLabel:
            halign: 'center'
            text: "TEST 4"
            font_size: '15sp'
            size: self.texture_size

此前使用几乎一致的配置实现ScrollView嵌套BoxLayout时运行正常,无法定位当前场景下Label顶部被截断的原因。

问题根因与修复方案

核心诱因

  1. ScrollView上硬编码size: (self.parent.width, self.parent.height),完全覆盖了父布局GridLayout给子控件分配的约束规则。外层GridLayout开启了row_force_default: True,会给每一行分配固定高度,手动给ScrollView硬设尺寸会导致它的布局锚点偏移,可视区域上移,把内部顶部的Label内容裁掉。之前用BoxLayout没出问题,是因为BoxLayout的子控件布局约束逻辑和开了强制行高的GridLayout不一致,硬设size的偏移问题没有显现。
  2. 外层GridLayout的行高计算依赖self.parent.height,MDBottomNavigationItem初始化阶段父布局高度还没完成测量,拿到的是初始默认值,会导致行高计算错误,挤压ScrollView的可用空间。
  3. 内部GridLayout的间距、ScrollView的滚动条宽度用了固定像素值,没有做屏幕密度适配,高分辨率设备上间距过大会把Label内容挤到可视区外。
  4. 所有Label直接用size: self.texture_size,没有预留字体上下边距,文本本身的渲染区域会贴边,容易出现上半部分被裁切的情况。

修复步骤

  • 删掉ScrollView上硬写的size: (self.parent.width, self.parent.height),ScrollView默认size_hint=(1,1),会自动适配父布局分配的行尺寸,不需要手动指定尺寸。
  • 调整外层GridLayout的行高计算逻辑,不要依赖未完成测量的父布局高度,把rows_minimum的计算基准换成GridLayout自身的实际高度,或者直接用row_default_height按比例分配行高。
  • 所有固定尺寸值做密度适配:把spacing: 60改成spacing: dp(60),bar_width: 20改成bar_width: dp(20),给内部GridLayout加padding: dp(10)留出边距。
  • 给ScrollView内的所有Label加padding_y: dp(5),给文本渲染预留上下边距,避免文本贴边被裁。

修复后的ScrollView段代码参考:

ScrollView:
    id: selectedScroll
    do_scroll_x: False
    do_scroll_y: True
    bar_width: dp(20)

    GridLayout:
        id: selectedGrid
        size_hint_y: None
        spacing: dp(60)
        cols: 2
        padding: dp(10)
        height: self.minimum_height
        MDLabel:
            halign: 'center'
            text: "TEST1"
            font_size: '15sp'
            theme_text_color: "Custom"
            text_color: get_color_from_hex("#08421e")
            size: self.texture_size
            padding_y: dp(5)
        # 其余Label按相同规则添加padding_y即可

内容的提问来源于stack exchange,提问作者Edric Antoine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:01:25