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

如何更新嵌套MDRecycleView中的数据?

嵌套MDRecycleView字体大小更新方案

方案一:利用全局属性绑定(推荐,无需手动刷新RecycleView)

这种方式不需要修改RecycleView的数据,也不用调用refresh_from_data(),通过Kivy的属性绑定机制自动同步字体大小:

  • 修改App类,添加可观察的font_size属性
    在MyApp类中添加font_size属性,使用StringProperty确保属性变化时能通知绑定的组件:

    from kivy.properties import StringProperty
    
    class MyApp(MDApp):
        font_size = StringProperty('20dp')  # 初始字体大小
        
        def on_start(self):
            # 原有代码不变
            data = []
            for i in range(10):
                innerData = []
                for i in range(2):
                    innerData.append({'item1': 'ITEM1',
                                      'item2': 'ITEM2'})
                data.append({'day': 'DAY','innerData': innerData})
            self.root.ids.mainScreenId.rvid.data = data
    
        # 原有build方法不变
    
  • 修改KV文件,将所有font_size绑定到app.font_size
    把所有组件的font_size引用从root.font_size或数据字段改为app.font_size:

    <Content>:
        bg_color: app.theme_cls.primary_dark
        item1: ''
        item2: ''
    
        MDGridLayout:
            rows: 2
            MDLabel:
                id: firstLabelId
                halign: 'center'
                text: root.item1
                font_size: app.font_size  # 绑定到全局属性
    
            MDLabel:
                id: secondLabelId
                halign: 'center'
                md_bg_color: root.bg_color
                text: root.item2
                font_size: app.font_size  # 绑定到全局属性
    
    <DailyService>:
        bg_color: app.theme_cls.primary_dark
        day: ''
        innerData: []
    
        MDGridLayout:
            rows: 2
            MDLabel:
                id: serviceId
                halign: 'center'
                text: root.day
                font_size: app.font_size  # 绑定到全局属性
    
        MDRecycleView:
            viewclass: 'Content'
            id: statisticContentRecycleViewId
            data: root.innerData
            do_scroll_y: False
            do_scroll_x: False
                            
            RecycleBoxLayout:
                default_size_hint: 1, 1
                orientation: 'vertical'
    
    <MainScreen>:
        name: 'mainScreen'
        rvid: myRv
    
        MDRelativeLayout:
            orientation: 'vertical'
    
            MDRecycleView:
                viewclass: 'DailyService'
                id: myRv
                RecycleBoxLayout:
                    default_size: None, dp(200)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'
    
            MDSlider:
                color: 'white'
                orientation: 'horizontal'
                size_hint: (0.2, 0.2)
                pos_hint: {"x":0.4, "top": 1}
                min: 10
                value: 20
                max: 30
                on_value: app.font_size = f"{int(self.value)}dp"  # 直接修改全局属性
    
  • 移除MainScreen中的fontSizeSlider方法
    因为滑块直接绑定到app.font_size,不需要再手动遍历数据和刷新RecycleView。

方案二:监听属性变化触发内部RecycleView刷新

如果坚持要通过更新数据的方式实现,可以通过在DailyService中监听font_size变化,自动刷新内部的RecycleView:

  • 修改DailyService类,添加属性监听

    from kivy.properties import StringProperty, ListProperty
    
    class DailyService(MDBoxLayout):
        font_size = StringProperty('15dp')
        innerData = ListProperty([])  # 改为ListProperty确保数据变化能被监听
    
        def on_font_size(self, instance, new_size):
            # 更新innerData中的font_size字段
            for item in self.innerData:
                item['font_size'] = new_size
            # 刷新内部RecycleView
            self.ids.statisticContentRecycleViewId.refresh_from_data()
    
  • 修改MainScreen的fontSizeSlider方法
    遍历外层数据更新font_size,然后刷新外层RecycleView:

    class MainScreen(Screen):
        def fontSizeSlider(self, value):
            rv = self.ids.myRv
            data = rv.data
            new_size = f"{int(value)}dp"
            for v in data:
                v['font_size'] = new_size
                # 更新innerData中的font_size
                for innerV in v['innerData']:
                    innerV['font_size'] = new_size
            rv.refresh_from_data()
    

这样当外层RecycleView刷新时,每个DailyService的font_size变化会触发内部RecycleView的刷新。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:07:08