如何在Kivy中实现MDCard展开与折叠的动画效果
我们可以直接用Kivy自带的Animation类实现高度平滑过渡,不需要引入额外组件,改动量很小。
具体修改步骤
1. 修改main.kv代码
MDScreen: MDBoxLayout: orientation: "vertical" MDCard: id: card orientation: "vertical" md_bg_color: .7, .7, .7, 1 padding: dp(20) size_hint: .5, None pos_hint: {"center_x": .5} MDIconButton: id: chevron_btn icon: "chevron-down" on_press: app.on_chevron() # 提前放置折叠内容容器,初始状态不占高度 Box: id: content_box orientation: "vertical" size_hint_y: None height: 0 Widget: <Box>: orientation: "vertical" size_hint_y: None height: self.minimum_height
2. 修改main.py代码
from kivymd.app import MDApp from kivy.lang import Builder from kivy.core.window import Window from kivymd.uix.boxlayout import MDBoxLayout from kivymd.uix.label import MDLabel # 导入Kivy原生动画类 from kivy.animation import Animation Window.size = (320, 600) class Box(MDBoxLayout): pass class MainApp(MDApp): def build(self): self.is_expanded = False self.root = Builder.load_file("main.kv") # 提前初始化折叠内容,避免每次展开重复创建控件 self.content = self.root.ids.content_box for i in range(10): self.content.add_widget(MDLabel(text=f"Lbl: {i}", size_hint=(1, None), height=20)) # 计算折叠状态下的卡片高度(仅包含按钮+上下内边距) self.collapsed_height = self.root.ids.chevron_btn.height + self.root.ids.card.padding[1] * 2 self.root.ids.card.height = self.collapsed_height return self.root def on_chevron(self): self.is_expanded = not self.is_expanded card = self.root.ids.card btn = self.root.ids.chevron_btn if self.is_expanded: # 展开动画:卡片高度变为折叠高度+内容总高度 target_height = self.collapsed_height + self.content.minimum_height anim = Animation(height=target_height, duration=0.3, t='out_cubic') anim.start(card) btn.icon = "chevron-up" else: # 折叠动画:卡片高度回到折叠状态高度 anim = Animation(height=self.collapsed_height, duration=0.3, t='out_cubic') anim.start(card) btn.icon = "chevron-down" if __name__ == "__main__": MainApp().run()
补充说明
- 动画的
duration参数控制动画时长,单位为秒,可根据需求自行调整 t参数是动画插值曲线,out_cubic是先快后慢的平滑效果,也可以换成linear、in_out_sine等其他曲线实现不同的动效- 如果需要动态加载内容,也可以在首次触发展开时再创建内容控件,后续切换状态直接修改高度即可
内容的提问来源于stack exchange,提问作者progS
相关产品推荐
相关产品推荐

