iOS Dropdown#
#
Added in version 2.0.1.
Provides liquid metaball morphing and glassmorphic dropdown behavior inspired by iOS visual effects.
Streamlines single tasks or options, keeping the user in flow;
Supports basic pop-ups and expanded full-size menus;
Blends and splits elements with dynamic GLSL shader animations;
Rendered as frosted glass with refraction, blur, and smooth corners;
Displays relevant info for quick changes or confirmations;
Anatomy#
Example#
from kivy.lang import Builder
from kivymd.app import MDApp
KV = '''
MDScreen:
FitImage:
id: bg_image
source: "https://picsum.photos/800/600?random=1"
IOSLiquidDropdownContainer:
id: dropdown_container
caller: trigger_btn
menu: menu_btn
IOSButton:
id: trigger_btn
size_hint: None, None
size: dp(56), dp(56)
border_radius: [dp(28)] * 4
target_background: bg_image
pos_hint: {"center_x": 0.5, "center_y": 0.65}
on_release: dropdown_container.toggle_dropdown()
IOSIconButton:
icon: "filter-variant"
theme_icon_color: "Custom"
icon_color: "white"
IOSButton:
id: menu_btn
adaptive_size: True
target_background: bg_image
border_radius: [dp(22)] * 4
on_release: dropdown_container.toggle_dropdown()
IOSButtonText:
text: "IOS Button"
theme_text_color: "Custom"
text_color: "white"
'''
class LiquidGlassDropdownDemo(MDApp):
def build(self):
return Builder.load_string(KV)
if __name__ == "__main__":
LiquidGlassDropdownDemo().run()
from kivy.metrics import dp
from kivymd.app import MDApp
from kivymd.uix.behaviors import IOSLiquidDropdownContainer
from kivymd.uix.button import IOSButton, IOSIconButton, IOSButtonText
from kivymd.uix.fitimage import FitImage
from kivymd.uix.screen import MDScreen
class LiquidGlassDropdownDemo(MDApp):
def build(self):
bg_image = FitImage(
id="bg_image",
source="https://picsum.photos/800/600?random=1",
)
dropdown_container = IOSLiquidDropdownContainer()
trigger_btn = IOSButton(
IOSIconButton(
icon="filter-variant",
theme_icon_color="Custom",
icon_color="white",
),
size_hint=[None, None],
size=[dp(56), dp(56)],
border_radius=[dp(28)] * 4,
target_background=bg_image,
pos_hint={"center_x": 0.5, "center_y": 0.65},
)
trigger_btn.bind(
on_release=lambda x: dropdown_container.toggle_dropdown()
)
menu = IOSButton(
IOSButtonText(
text="IOS Button",
theme_text_color="Custom",
text_color="white",
),
adaptive_size=True,
border_radius=[dp(22)] * 4,
target_background=bg_image,
)
menu.bind(
on_release=lambda x: dropdown_container.toggle_dropdown()
)
dropdown_container.widgets = [
trigger_btn,
menu,
]
dropdown_container.caller = trigger_btn
dropdown_container.menu = menu
return MDScreen(
bg_image,
dropdown_container,
)
if __name__ == "__main__":
LiquidGlassDropdownDemo().run()
API - kivymd.uix.behaviors.ios.dropdown_behavior#
- class kivymd.uix.behaviors.ios.dropdown_behavior.IOSLiquidDropdownBehavior(*args, **kwargs)#
Behavior class responsible for orchestrating the liquid metaball transition, shader uniform synchronization, and wobble dynamics between a trigger button and a dropdown menu.
For more information see in the
IOSBaseGlassBehaviorclass documentation.- direction#
Direction in which the dropdown menu expands relative to the caller button.
Available options: ‘bottom’, ‘top’, ‘left’, ‘right’, ‘bottom-left’, ‘bottom-right’, ‘top-left’, ‘top-right’.
directionis anOptionPropertyand defaults to ‘bottom’.
- spacing#
Gap between the trigger button and the dropdown menu.
spacingis aNumericPropertyand defaults to dp(12).
- open_transition#
Easing curve transition type for the expansion animation.
open_transitionis aStringPropertyand defaults to ‘out_cubic’.
- open_duration#
Total time in seconds required to fully expand the dropdown menu.
open_durationis aNumericPropertyand defaults to 0.6.
- close_transition#
Easing curve transition type for the collapse animation.
close_transitionis aStringPropertyand defaults to ‘in_out_cubic’.
- close_duration#
Total time in seconds required to collapse back into the trigger button.
close_durationis aNumericPropertyand defaults to 0.45.
- viscosity#
Maximum smooth-minimum blending factor (k) controlling the liquid neck stretch.
viscosityis aNumericPropertyand defaults to dp(100).
- is_open#
State flag indicating whether the dropdown menu is currently open.
is_openis aBooleanPropertyand defaults to False.
- btn_fade_out_transition#
Easing curve transition for hiding trigger button on open.
btn_fade_out_transitionis aStringPropertyand defaults to ‘out_quad’.
- btn_fade_in_transition#
Easing curve transition for restoring trigger button on close.
btn_fade_in_transitionis aStringPropertyand defaults to ‘in_quad’.
Easing curve transition for revealing dropdown menu content on open completion.
menu_fade_in_transitionis aStringPropertyand defaults to ‘out_quad’.
Easing curve transition for hiding dropdown menu content on close.
menu_fade_out_transitionis aStringPropertyand defaults to ‘out_quad’.
- k_ramp_up_transition#
Easing curve transition for increasing viscosity (k).
k_ramp_up_transitionis aStringPropertyand defaults to ‘out_quad’.
- k_ramp_down_transition#
Easing curve transition for collapsing viscosity (k).
k_ramp_down_transitionis aStringPropertyand defaults to ‘in_cubic’.
- on_parent(instance, parent)#
Cleanup when removing a widget from the layout.
- on_touch_down(touch)#
- on_touch_move(touch)#
- on_touch_up(touch)#
Dynamically repositions the dropdown menu relative to the trigger button based on direction and properties.
- class kivymd.uix.behaviors.ios.dropdown_behavior.IOSLiquidDropdownContainer(*args, **kwargs)#
Container handling liquid drop transition logic.
For more information see in the
DeclarativeBehaviorandIOSLiquidDropdownBehaviorandFloatLayoutandMDAdaptiveWidgetclass documentation.- caller#
A widget trigger (button) that initiates the droplet animation.
calleris aObjectPropertyand defaults to None.
Drop-down menu.
menuis aObjectPropertyand defaults to None.
- on_touch_down(touch)#
Receive a touch down event.
- Parameters:
- touch:
MotionEventclass Touch received. The touch is in parent coordinates. See
relativelayoutfor a discussion on coordinate systems.
- touch:
- Returns:
bool If True, the dispatching of the touch event will stop. If False, the event will continue to be dispatched to the rest of the widget tree.