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

RecycleView中MDLabel更新数据后文本丢失问题求助

问题描述

我有loginScreen和mainScreen两个屏幕,在mainScreen中使用RecycleView展示MDLabel。首次进入mainScreen时一切正常,但每当刷新RecycleView的数据后,滚动界面时部分标签的文本会出现消失或重现的情况。当我使用普通Kivy Label替代MDLabel时,不会出现这种异常现象。请问是我的代码存在问题,还是在RecycleView中使用MDLabel会出现此类预期情况?


代码文件

main.py

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivymd.color_definitions import colors
from kivymd.uix.boxlayout import MDBoxLayout
import random

class DailyService(MDBoxLayout):
    pass

class MainScreen(Screen):
    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

    def switchButton(self):
        self.manager.switchToLoginScreen()

class LoginScreen(Screen):
    def __init__(self, **kwargs):
        super(LoginScreen, self).__init__(**kwargs)

    def switchButton(self):
        self.manager.switchToMainScreen()
    
class MyScreenManager(ScreenManager):
    def __init__(self, **kwargs):
        super(MyScreenManager, self).__init__(**kwargs)
        #self.current = 'loginScreen'
        
    def switchToMainScreen(self):
        data = []
        for i in range(20):
            k = random.randint(0, 9)
            if k%2 == 0:
                color =  colors['BlueGray']['700']
            else:
                color =  colors['Green']['700']
            data.append({'day': 'DAY',
                         'service': 'SERVICE',
                         'bg_color':  color})
        self.mainScreen.rvid.data = data
        self.current = 'mainScreen'

    def switchToLoginScreen(self):
        self.current = 'loginScreen'


class MyApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = 'Dark'
        self.theme_cls.primary_palette = 'Blue'
        self.theme_cls.accent_palette = 'Amber'
        return Builder.load_file('main.kv')

if __name__ == '__main__':
    MyApp().run()

main.kv

<LoginScreen>:
    name: 'loginScreen'

    Button:
        text: 'MAIN'
        on_release: root.switchButton()
        
<DailyService>:
    bg_color: app.theme_cls.primary_dark
    day: ''
    service: ''
    
    MDGridLayout:
        rows: 2
        MDLabel:
            halign: 'center'
            text: root.day

        MDLabel:
            halign: 'center'
            md_bg_color: root.bg_color
            text: root.service

        
<MainScreen>:
    name: 'mainScreen'
    rvid: myRv

    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'
            
    Button:
        pos_hint:{"x":0.5,'bottom': 1}
        size_hint: 0.4, 0.1
        text: 'LOGIN'
        on_release: root.switchButton()

MyScreenManager:
    loginScreen: loginScreenId
    mainScreen: mainScreenId

    LoginScreen:
        id: loginScreenId
        
    MainScreen:
        id: mainScreenId

截图

  • 首次进入mainScreen:
    首次进入mainScreen截图

  • 更新数据后再次进入mainScreen:
    更新数据后再次进入mainScreen截图


解答

这是MDLabel与RecycleView复用机制的兼容问题导致的,并非你的代码逻辑错误。RecycleView会复用列表项优化性能,但MDLabel内部的部分状态在复用过程中没有被正确重置,进而引发文本显示异常。

可以通过以下方式解决:

  1. 强制MDLabel刷新:在DailyService类中添加属性监听,手动触发MDLabel的纹理更新。
    修改DailyService类:

    class DailyService(MDBoxLayout):
        def on_day(self, instance, value):
            self.ids.day_label.texture_update()
        def on_service(self, instance, value):
            self.ids.service_label.texture_update()
    

    同时在kv文件中为MDLabel添加id:

    <DailyService>:
        bg_color: app.theme_cls.primary_dark
        day: ''
        service: ''
        
        MDGridLayout:
            rows: 2
            MDLabel:
                id: day_label
                halign: 'center'
                text: root.day
    
            MDLabel:
                id: service_label
                halign: 'center'
                md_bg_color: root.bg_color
                text: root.service
    
  2. 替换为原生Label:如果不需要MDLabel的特殊样式,直接使用Kivy原生Label即可避免该问题,这也是最直接的解决方案。

  3. 升级KivyMD版本:新版本的KivyMD可能已经修复了这个兼容性问题,可以尝试更新到最新版。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 14:13:24