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:

解答
这是MDLabel与RecycleView复用机制的兼容问题导致的,并非你的代码逻辑错误。RecycleView会复用列表项优化性能,但MDLabel内部的部分状态在复用过程中没有被正确重置,进而引发文本显示异常。
可以通过以下方式解决:
强制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替换为原生Label:如果不需要MDLabel的特殊样式,直接使用Kivy原生Label即可避免该问题,这也是最直接的解决方案。
升级KivyMD版本:新版本的KivyMD可能已经修复了这个兼容性问题,可以尝试更新到最新版。
内容的提问来源于stack exchange,提问作者domdrag
相关产品推荐
相关产品推荐

