I am searching for a way to animate my MDCard when expanding or collapsing.
In my example, when I click my MDIconButton I want an animation that slowly expands or collapses the card. I know there is an MDExpansionsPanel widget but for now, I'm not interested in using this. Is there an easy way to implement an animation that is similar to the ExpansionPanel?
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
height: self.minimum_height
pos_hint: {"center_x": .5}
MDIconButton:
icon: "chevron-down"
on_press: app.on_chevron()
Widget:
<Box>:
orientation: "vertical"
size_hint_y: None
height: self.minimum_height
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
Window.size = {320, 600}
class Box(MDBoxLayout):
pass
class MainApp(MDApp):
def build(self):
self.is_expanded = False
return Builder.load_file("main.kv")
def on_chevron(self):
self.is_expanded = not self.is_expanded
card_layout = self.root.ids.card
if self.is_expanded:
item = Box()
for i in range(10):
item.add_widget(MDLabel(text=f"Lbl: {i}", size_hint=(1, None), height=20))
card_layout.add_widget(item)
else:
card_layout.remove_widget(card_layout.children[0])
if __name__ == "__main__":
MainApp().run()
You can use Animation to do that. Here is a modified version of your on_chevron()
method that uses Animation
:
def on_chevron(self):
self.is_expanded = not self.is_expanded
card_layout = self.root.ids.card
if self.is_expanded:
item = Box()
labels = []
for i in range(10):
# initialze Label with 0 height and font_size
l = Label(text=f"Lbl: {i}", color=(0,0,0,1), font_size=0, size_hint=(1, None), height=0)
item.add_widget(l)
labels.append(l)
card_layout.add_widget(item)
self.animate_labels(labels)
else:
card_layout.remove_widget(card_layout.children[0])
def animate_labels(self, labels):
anims = []
for i in range(len(labels)):
anims.append(Animation(height=20, font_size=15)) # animate height and font_size
for i in range(len(labels)):
anims[i].start(labels[i]) # start animations
I switched your MDLabel
to Label
just because MDLabel
meddles with sizes. There may be a way to do this with the MDLabel
.