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

如何解决KivyMD中on_enter方法重复加载列表的问题

问题根源

on_enter是MDScreen组件每次进入当前屏幕时必定触发的生命周期回调,现有代码中list_status方法没有做任何前置清理或加载判断,每次执行都会直接读取json数据后,循环向id为storyline的容器内追加新的CircularAvatarImage控件,多次进入页面就会不断累积重复控件,最终出现列表重复展示的问题。

修复方案

方案1:加载前清空容器(适配数据需要实时更新的场景,最常用)

在循环添加新控件前,先清空storyline容器内的历史动态控件,保证每次加载生成的都是全新的列表,从根源避免重复累积。
基础版(容器内无提前写好的固定静态控件时使用)代码如下:

class HomePage(MDScreen):
    profile_pics = StringProperty("")
    balance = StringProperty("")

    def on_enter(self, *args):
        self.list_status()
        self.list_post()
        self.get_all_info()

    def list_status(self):
        # 先清空容器内所有已有子控件
        self.ids.storyline.clear_widgets()
        with open("asset/data/store.json") as f_obj:
            data = json.load(f_obj)
            for name in data:
                self.ids.storyline.add_widget(CircularAvatarImage(
                    avatar=data[name]['avatar'],
                    name=name
                ))

如果storyline容器内有你在kv文件中预先写好、不需要被删除的固定控件,不要直接用clear_widgets(),可以给动态添加的头像控件打专属标记,清空时只删除标记的动态控件即可:

def list_status(self):
    # 仅清理之前动态添加的头像控件,保留静态内容
    for child in list(self.ids.storyline.children):
        if hasattr(child, "status_item_tag"):
            self.ids.storyline.remove_widget(child)
    
    with open("asset/data/store.json") as f_obj:
        data = json.load(f_obj)
        for name in data:
            avatar_item = CircularAvatarImage(
                avatar=data[name]['avatar'],
                name=name
            )
            # 给动态控件打标记
            avatar_item.status_item_tag = True
            self.ids.storyline.add_widget(avatar_item)

方案2:增加首次加载标记(适配静态不变数据场景,性能更好)

如果store.json里的状态数据在App运行过程中不会发生变化,不需要每次进入页面都重新读取渲染,可以新增一个布尔类型的标记位,仅在第一次进入页面时执行一次list_status的加载逻辑,后续进入页面直接跳过该方法的重复执行,自然不会出现重复添加的问题。
代码示例:

class HomePage(MDScreen):
    profile_pics = StringProperty("")
    balance = StringProperty("")
    # 新增加载标记,默认未加载
    _status_list_loaded = False

    def on_enter(self, *args):
        # 仅首次进入时加载状态列表
        if not self._status_list_loaded:
            self.list_status()
            self._status_list_loaded = True
        self.list_post()
        self.get_all_info()

    def list_status(self):
        with open("asset/data/store.json") as f_obj:
            data = json.load(f_obj)
            for name in data:
                self.ids.storyline.add_widget(CircularAvatarImage(
                    avatar=data[name]['avatar'],
                    name=name
                ))
选型参考
  • 若状态、帖子数据需要每次进入页面都同步为最新内容,选择方案1
  • 若数据为固定静态内容、运行期间不会修改,选择方案2可以减少不必要的文件读取和控件渲染,性能更优

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:09:24