Set of widgets for Kivy inspired by Google's Material Design
—
Animation and visual effect components that bring Material Design motion to life. These components include screen transitions, hero animations, ripple effects, elevation behaviors, and other motion elements that enhance user experience through smooth, meaningful animations.
Transition animations for screen changes and navigation flow.
class MDFadeSlideTransition:
"""
Fade slide transition for screen manager.
Combines fade and slide animations for smooth screen transitions
with Material Design motion principles.
"""
direction: str # Transition direction: "left", "right", "up", "down"
duration: float # Transition duration in seconds
def start(self, instance_screen_manager):
"""Start the transition animation."""
def stop(self, instance_screen_manager):
"""Stop the transition animation."""
class MDSlideTransition:
"""
Slide transition for screen manager.
Pure slide animation for screen transitions with configurable
direction and timing.
"""
direction: str # Slide direction: "left", "right", "up", "down"
duration: float # Transition duration in seconds
class MDSwapTransition:
"""
Swap transition for screen manager.
Swap animation that flips between screens with a rotation effect.
"""
duration: float # Transition duration in secondsHero animations for smooth element transitions between screens.
class MDHeroFrom:
"""
Hero animation source widget.
Marks a widget as the source of a hero animation that will
smoothly transition to a destination widget on another screen.
"""
tag: str # Unique identifier linking source to destination
# Animation properties
duration: float # Animation duration in seconds
transition: str # Animation transition type
def start_hero_animation(self):
"""Start the hero animation to destination."""
class MDHeroTo:
"""
Hero animation destination widget.
Marks a widget as the destination of a hero animation from
a source widget on another screen.
"""
tag: str # Unique identifier linking to source widget
# Animation properties
duration: float # Animation duration in seconds
transition: str # Animation transition type
def complete_hero_animation(self):
"""Complete the hero animation from source."""Touch feedback effects that provide visual confirmation of user interactions.
class CircularRippleBehavior:
"""
Circular ripple effect behavior.
Mixin behavior that adds circular ripple effects to widgets
when touched, following Material Design interaction feedback.
"""
ripple_rad_default: float # Default ripple radius
ripple_color: str | list # Ripple color
ripple_alpha: float # Ripple opacity (0-1)
ripple_scale: float # Ripple scale factor
ripple_duration_in_slow: float # Slow ripple duration
ripple_duration_in_fast: float # Fast ripple duration
ripple_duration_out: float # Ripple fade out duration
# Ripple behavior
ripple_func_in: str # Animation function for ripple in
ripple_func_out: str # Animation function for ripple out
def lay_canvas_instructions(self):
"""Set up canvas instructions for ripple rendering."""
def start_ripple(self):
"""Start the ripple animation."""
def finish_ripple(self):
"""Finish the ripple animation."""
class RectangularRippleBehavior:
"""
Rectangular ripple effect behavior.
Mixin behavior that adds rectangular ripple effects to widgets,
typically used for rectangular buttons and cards.
"""
ripple_color: str | list # Ripple color
ripple_alpha: float # Ripple opacity (0-1)
ripple_scale: float # Ripple scale factor
ripple_duration_in: float # Ripple animation in duration
ripple_duration_out: float # Ripple animation out duration
# Ripple positioning
ripple_func_in: str # Animation function for ripple in
ripple_func_out: str # Animation function for ripple outShadow and elevation effects that create depth and hierarchy.
class CircularElevationBehavior:
"""
Circular elevation behavior for round widgets.
Provides elevation shadows for circular widgets like FABs
with appropriate shadow rendering.
"""
elevation: float # Elevation level (0-24)
shadow_radius: float # Shadow blur radius
shadow_softness: float # Shadow edge softness
shadow_offset: list # Shadow offset [x, y]
shadow_color: str | list # Shadow color
def update_elevation(self, elevation: float):
"""Update widget elevation level."""
class RectangularElevationBehavior:
"""
Rectangular elevation behavior for rectangular widgets.
Provides elevation shadows for rectangular widgets like cards
and buttons with proper shadow geometry.
"""
elevation: float # Elevation level (0-24)
shadow_radius: float # Shadow blur radius
shadow_softness: float # Shadow edge softness
shadow_offset: list # Shadow offset [x, y]
shadow_color: str | list # Shadow color
class RoundedRectangularElevationBehavior:
"""
Rounded rectangular elevation behavior.
Elevation behavior for widgets with rounded corners,
providing appropriate shadow rendering for rounded rectangles.
"""
elevation: float # Elevation level (0-24)
radius: list # Corner radius [top-left, top-right, bottom-right, bottom-left]
shadow_radius: float # Shadow blur radius
shadow_softness: float # Shadow edge softness
class CommonElevationBehavior:
"""
Common elevation behavior with shared functionality.
Base behavior providing common elevation properties
and methods for all elevation behaviors.
"""
elevation: float # Elevation level (0-24)
def set_elevation(self, elevation: float):
"""Set widget elevation level."""
class FakeCircularElevationBehavior:
"""
Fake circular elevation behavior.
Lightweight elevation effect that simulates shadows
without heavy rendering for performance optimization.
"""
elevation: float # Elevation level
shadow_softness: float # Shadow softness
class FakeRectangularElevationBehavior:
"""
Fake rectangular elevation behavior.
Lightweight elevation effect for rectangular widgets
with optimized rendering performance.
"""
elevation: float # Elevation level
shadow_softness: float # Shadow softnessReusable animation behaviors for common motion patterns.
class MagicBehavior:
"""
Magic animation behavior.
Provides magical transition effects and animations
for special interaction patterns.
"""
magic_speed: float # Animation speed
def grow(self):
"""Grow animation effect."""
def shrink(self):
"""Shrink animation effect."""
class RotateBehavior:
"""
Rotation animation behavior.
Mixin behavior that adds rotation capabilities to widgets
with smooth animation support.
"""
rotate_value_angle: float # Current rotation angle
rotate_value_axis: tuple # Rotation axis (x, y, z)
def start_rotation(self, angle: float, duration: float = 1.0):
"""
Start rotation animation.
Args:
angle (float): Target rotation angle in degrees
duration (float): Animation duration in seconds
"""
def stop_rotation(self):
"""Stop rotation animation."""
class ScaleBehavior:
"""
Scale animation behavior.
Mixin behavior that adds scaling capabilities to widgets
with smooth scale transitions.
"""
scale_value_x: float # X-axis scale factor
scale_value_y: float # Y-axis scale factor
scale_value_z: float # Z-axis scale factor
def start_scale(self, scale: float, duration: float = 1.0):
"""
Start scale animation.
Args:
scale (float): Target scale factor
duration (float): Animation duration in seconds
"""
def stop_scale(self):
"""Stop scale animation."""
class StencilBehavior:
"""
Stencil animation behavior.
Provides stencil-based animation effects for masking
and reveal animations.
"""
def apply_stencil(self):
"""Apply stencil effect."""
def remove_stencil(self):
"""Remove stencil effect."""Interactive behaviors that respond to user input with animations.
class TouchBehavior:
"""
Touch behavior for handling touch interactions.
Provides enhanced touch handling with animation feedback
and gesture recognition.
"""
touch_color: str | list # Touch feedback color
def on_touch_down(self, touch):
"""Handle touch down with animation."""
def on_touch_move(self, touch):
"""Handle touch move with feedback."""
def on_touch_up(self, touch):
"""Handle touch up with animation."""
class HoverBehavior:
"""
Hover behavior for desktop interactions.
Provides hover state animations and effects for
desktop applications with mouse input.
"""
hover_color: str | list # Hover state color
def on_enter(self):
"""Handle mouse enter with animation."""
def on_leave(self):
"""Handle mouse leave with animation."""Tutorial and onboarding animations that highlight UI elements.
class MDTapTargetView:
"""
Material Design tap target view.
Creates animated tutorial overlays that highlight specific
UI elements and provide contextual information for user onboarding.
"""
# Target widget
widget: object # Widget to highlight
# Content
title_text: str # Tap target title
description_text: str # Tap target description
widget_position: str # Target widget position: "left", "right", "top", "bottom", "center"
# Visual styling
outer_circle_color: str | list # Outer circle color
target_circle_color: str | list # Target circle color
title_text_color: str | list # Title text color
description_text_color: str | list # Description text color
# Animation
outer_circle_alpha: float # Outer circle opacity
target_radius: float # Target circle radius
# Behavior
cancelable: bool # Allow dismissing by tapping outside
def start(self):
"""Start the tap target animation."""
def stop(self):
"""Stop and hide the tap target view."""
def on_target_click(self):
"""Called when target area is clicked."""
def on_target_cancel(self):
"""Called when tap target is cancelled."""from kivymd.uix.screenmanager import MDScreenManager
from kivymd.uix.screen import MDScreen
from kivymd.uix.transition import MDFadeSlideTransition, MDSlideTransition
class MyApp(MDApp):
def build(self):
# Create screen manager with custom transition
sm = MDScreenManager(
transition=MDFadeSlideTransition(
direction="left",
duration=0.3
)
)
# Create screens
screen1 = MDScreen(name="screen1")
screen2 = MDScreen(name="screen2")
# Add screens
sm.add_widget(screen1)
sm.add_widget(screen2)
return sm
def switch_to_slide_transition(self):
"""Switch to slide transition."""
self.root.transition = MDSlideTransition(
direction="right",
duration=0.4
)from kivymd.uix.hero import MDHeroFrom, MDHeroTo
from kivymd.uix.button import MDIconButton
from kivymd.uix.card import MDCard
class SourceScreen(MDScreen):
def build(self):
# Hero source - small FAB
hero_from = MDHeroFrom(
tag="fab_hero",
size_hint=(None, None),
size=("56dp", "56dp"),
pos_hint={"center_x": 0.1, "center_y": 0.1}
)
fab = MDIconButton(
icon="plus",
theme_icon_color="Custom",
icon_color="white",
md_bg_color="primary",
on_release=self.go_to_destination
)
hero_from.add_widget(fab)
return hero_from
def go_to_destination(self, instance):
"""Navigate to destination screen."""
self.manager.current = "destination"
class DestinationScreen(MDScreen):
def build(self):
# Hero destination - large card
hero_to = MDHeroTo(
tag="fab_hero",
size_hint=(0.8, 0.6),
pos_hint={"center_x": 0.5, "center_y": 0.5}
)
card = MDCard(
md_bg_color="primary",
elevation=8,
radius=[16, 16, 16, 16]
)
hero_to.add_widget(card)
return hero_tofrom kivymd.uix.button import MDRaisedButton
from kivymd.uix.behaviors import CircularRippleBehavior
from kivymd.uix.card import MDCard
class RippleCard(MDCard, CircularRippleBehavior):
"""Card with ripple effect."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.ripple_color = [0.2, 0.6, 1, 0.3] # Blue ripple
self.ripple_alpha = 0.3
self.ripple_scale = 2.0
class MyApp(MDApp):
def build(self):
layout = MDBoxLayout(
orientation="vertical",
spacing="16dp",
padding="16dp"
)
# Button with default ripple
button = MDRaisedButton(
text="Default Ripple",
pos_hint={"center_x": 0.5}
)
# Card with custom ripple
ripple_card = RippleCard(
size_hint=(0.8, None),
height="100dp",
pos_hint={"center_x": 0.5},
elevation=4,
md_bg_color="surface"
)
layout.add_widget(button)
layout.add_widget(ripple_card)
return layoutfrom kivymd.uix.card import MDCard
from kivymd.uix.behaviors import RectangularElevationBehavior
from kivymd.uix.button import MDRaisedButton
class ElevatedCard(MDCard):
"""Card with animated elevation."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.elevation = 2
self.bind(on_touch_down=self.elevate_on_touch)
self.bind(on_touch_up=self.restore_elevation)
def elevate_on_touch(self, instance, touch):
"""Increase elevation on touch."""
if self.collide_point(*touch.pos):
Animation(elevation=8, duration=0.1).start(self)
def restore_elevation(self, instance, touch):
"""Restore normal elevation."""
Animation(elevation=2, duration=0.2).start(self)
class MyApp(MDApp):
def build(self):
layout = MDBoxLayout(
orientation="vertical",
spacing="24dp",
padding="16dp"
)
# Cards with different elevations
elevations = [2, 4, 8, 16]
for elev in elevations:
card = ElevatedCard(
size_hint=(0.8, None),
height="80dp",
pos_hint={"center_x": 0.5},
elevation=elev,
md_bg_color="surface"
)
# Add label showing elevation
label = MDLabel(
text=f"Elevation: {elev}",
halign="center",
theme_text_color="Primary"
)
card.add_widget(label)
layout.add_widget(card)
return layoutfrom kivymd.uix.behaviors import RotateBehavior, ScaleBehavior
from kivymd.uix.button import MDIconButton
from kivy.animation import Animation
class AnimatedButton(MDIconButton, RotateBehavior, ScaleBehavior):
"""Button with rotation and scale animations."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.bind(on_release=self.animate)
def animate(self, instance):
"""Trigger animations on button press."""
# Rotate 360 degrees
anim_rotate = Animation(
rotate_value_angle=360,
duration=1.0
)
# Scale up then down
anim_scale_up = Animation(
scale_value_x=1.5,
scale_value_y=1.5,
duration=0.2
)
anim_scale_down = Animation(
scale_value_x=1.0,
scale_value_y=1.0,
duration=0.2
)
# Chain animations
anim_scale = anim_scale_up + anim_scale_down
# Start animations
anim_rotate.start(self)
anim_scale.start(self)
class MyApp(MDApp):
def build(self):
return AnimatedButton(
icon="star",
pos_hint={"center_x": 0.5, "center_y": 0.5},
theme_icon_color="Custom",
icon_color="gold"
)from kivymd.uix.taptargetview import MDTapTargetView
from kivymd.uix.button import MDFloatingActionButton
class MyApp(MDApp):
def build(self):
layout = MDBoxLayout()
# FAB that will be highlighted
self.fab = MDFloatingActionButton(
icon="plus",
pos_hint={"center_x": 0.8, "center_y": 0.2},
on_release=self.fab_pressed
)
layout.add_widget(self.fab)
# Show tutorial after a delay
Clock.schedule_once(self.show_tutorial, 2)
return layout
def show_tutorial(self, dt):
"""Show tap target tutorial."""
tap_target = MDTapTargetView(
widget=self.fab,
title_text="Add New Item",
description_text="Tap this button to create a new item in your list. You can customize the item details after creation.",
widget_position="left_top",
title_text_color=[1, 1, 1, 1],
description_text_color=[0.9, 0.9, 0.9, 1],
outer_circle_color=[0.2, 0.6, 1, 0.8],
target_circle_color=[1, 1, 1, 1],
cancelable=True
)
tap_target.start()
def fab_pressed(self, instance):
"""Handle FAB press."""
print("FAB pressed - tutorial completed!")from kivy.animation import Animation
from kivymd.uix.card import MDCard
from kivymd.uix.label import MDLabel
class AnimatedCard(MDCard):
"""Card with complex animation sequence."""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.elevation = 2
self.setup_animations()
def setup_animations(self):
"""Set up animation sequence."""
# Animation sequence: fade in -> scale up -> bounce -> fade out
self.fade_in = Animation(
opacity=1,
duration=0.5
)
self.scale_up = Animation(
size_hint=(0.9, 0.4),
duration=0.3
)
self.bounce = Animation(
pos_hint={"center_y": 0.6},
duration=0.2
) + Animation(
pos_hint={"center_y": 0.5},
duration=0.2
)
self.fade_out = Animation(
opacity=0,
duration=0.5
)
def start_animation_sequence(self):
"""Start the complete animation sequence."""
# Chain animations
sequence = self.fade_in + self.scale_up + self.bounce
sequence.bind(on_complete=self.on_animation_complete)
sequence.start(self)
def on_animation_complete(self, animation, widget):
"""Handle animation completion."""
Clock.schedule_once(lambda dt: self.fade_out.start(self), 2)
class MyApp(MDApp):
def build(self):
layout = MDBoxLayout()
# Create animated card
card = AnimatedCard(
size_hint=(0.6, 0.3),
pos_hint={"center_x": 0.5, "center_y": 0.5},
opacity=0,
md_bg_color="primary"
)
label = MDLabel(
text="Animated Card",
halign="center",
theme_text_color="Custom",
text_color=[1, 1, 1, 1]
)
card.add_widget(label)
# Start animation after delay
Clock.schedule_once(
lambda dt: card.start_animation_sequence(),
1
)
layout.add_widget(card)
return layoutInstall with Tessl CLI
npx tessl i tessl/pypi-kivymd