ExpansionTile
A single-line ListTile with an expansion arrow icon that expands or collapses the tile to reveal or hide its controls.
Example:
ft.ExpansionTile(
width=400,
title="Account",
subtitle="Manage profile and security",
expanded=True,
controls=[
ft.ListTile(title=ft.Text("Profile")),
ft.ListTile(title=ft.Text("Security")),
],
)

Inherits: LayoutControl, AdaptiveControl
Properties
affinity- Typically used to force the expansion arrow icon to the tile's leading or trailing edge.animation_style- Defines the animation style (curve and duration) for this tile's expansion and collapse.bgcolor- The color to display behind the sublist when expanded.clip_behavior- Defines how the content of this tile is clipped.collapsed_bgcolor- Defines the background color of this tile when the sublist is collapsed (expanded is False).collapsed_icon_color- The icon color of this tile's expansion arrow icon when the sublist is collapsed (expanded is False).collapsed_shape- The tile's border shape when the sublist is collapsed.collapsed_text_color- The color of this tile's titles when the sublist is collapsed (expanded is False).controls- The controls to be displayed when this tile expanded.controls_padding- Defines the padding around the controls.dense- Whether this list tile is part of a vertically dense list.enable_feedback- Whether detected gestures should provide acoustic and/or haptic feedback.expanded- The expansion state of this tile.expanded_alignment- Defines the alignment of controls, which are arranged in a column when the tile is expanded.expanded_cross_axis_alignment- Defines the alignment of each child control within controls when the tile is expanded.icon_color- The icon color of this tile's expansion arrow icon when the sublist is expanded.leading- A Control to display before the title.maintain_state- A boolean value which defines whether the state of the controls is maintained when this tile expanded and collapses.min_tile_height- The minimum height of this tile.shape- The border shape of this tile when the sublist is expanded.show_trailing_icon- Whether this tile should build/show a default trailing icon, if trailing isNone.subtitle- Additional content displayed below the title.text_color- The color of this tile's titles when the sublist is expanded.tile_padding- Defines the tile's padding.title- A Control to display as primary content of this tile.trailing- A Control to display after the title.visual_density- Defines how compact this tile's layout will be.
Events
on_change- Called when a user clicks or taps the list tile.
Examples
Basic Example
import flet as ft
def main(page: ft.Page):
page.theme_mode = ft.ThemeMode.LIGHT
page.spacing = 0
page.padding = 0
def handle_tile_change(e: ft.Event[ft.ExpansionTile]):
page.show_dialog(
ft.SnackBar(
duration=1000,
content=ft.Text(
value=(
f"ExpansionTile was "
f"{'expanded' if e.data == 'true' else 'collapsed'}"
)
),
)
)
if e.control.trailing:
e.control.trailing.icon = (
ft.Icons.ARROW_DROP_DOWN
if e.control.trailing.icon == ft.Icons.ARROW_DROP_DOWN_CIRCLE
else ft.Icons.ARROW_DROP_DOWN_CIRCLE
)
e.control.trailing.update()
page.add(
ft.SafeArea(
content=ft.Column(
spacing=0,
controls=[
ft.ExpansionTile(
expanded=True,
title=ft.Text("ExpansionTile 1"),
subtitle=ft.Text("Trailing expansion arrow icon"),
affinity=ft.TileAffinity.PLATFORM,
maintain_state=True,
collapsed_text_color=ft.Colors.RED,
text_color=ft.Colors.RED,
controls=[
ft.ListTile(title=ft.Text("This is sub-tile number 1.1")),
ft.ListTile(title=ft.Text("This is sub-tile number 1.2")),
],
),
ft.ExpansionTile(
expanded=True,
title=ft.Text("ExpansionTile 2"),
subtitle=ft.Text("Custom expansion arrow icon"),
trailing=ft.Icon(ft.Icons.ARROW_DROP_DOWN),
collapsed_text_color=ft.Colors.GREEN,
text_color=ft.Colors.GREEN,
on_change=handle_tile_change,
controls=[
ft.ListTile(title=ft.Text("This is sub-tile number 2.1")),
ft.ListTile(title=ft.Text("This is sub-tile number 2.2")),
],
),
ft.ExpansionTile(
expanded=True,
title=ft.Text("ExpansionTile 3"),
subtitle=ft.Text("Leading expansion arrow icon"),
affinity=ft.TileAffinity.LEADING,
collapsed_text_color=ft.Colors.BLUE_800,
text_color=ft.Colors.BLUE_200,
controls=[
ft.ListTile(title=ft.Text("This is sub-tile number 3.1")),
ft.ListTile(title=ft.Text("This is sub-tile number 3.2")),
],
),
],
),
),
)
if __name__ == "__main__":
ft.run(main)

Programmatic expansion/collapse
import flet as ft
def main(page: ft.Page):
page.spacing = 20
tile = ft.ExpansionTile(
title=ft.Text("I am the title of this tile.", weight=ft.FontWeight.BOLD),
subtitle=ft.Text("This is the subtitle."),
affinity=ft.TileAffinity.LEADING,
controls=[ft.Text("👻", size=80)],
expanded=True,
on_change=lambda e: print(f"Tile was {'expanded' if e.data else 'collapsed'}"),
)
def expand_tile(_: ft.Event[ft.FilledButton]):
tile.expanded = True
tile.update()
def collapse_tile(_: ft.Event[ft.OutlinedButton]):
tile.expanded = False
tile.update()
page.add(
ft.SafeArea(
content=ft.Column(
controls=[
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
ft.FilledButton("Expand Tile", on_click=expand_tile),
ft.OutlinedButton("Collapse Tile", on_click=collapse_tile),
],
),
tile,
],
),
)
)
if __name__ == "__main__":
ft.run(main)
Custom animations
import flet as ft
def main(page: ft.Page):
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
page.spacing = 20
tile = ft.ExpansionTile(
expanded=True,
title=ft.Text("Expand/Collapse me while being attentive to the animations!"),
controls=[
ft.ListTile(title=ft.Text("Sub-item 1")),
ft.ListTile(title=ft.Text("Sub-item 2")),
ft.ListTile(title=ft.Text("Sub-item 3")),
],
)
def switch_animation(e: ft.Event[ft.CupertinoSlidingSegmentedButton]):
if e.control.selected_index == 0:
tile.animation_style = None
elif e.control.selected_index == 1:
tile.animation_style = ft.AnimationStyle(
curve=ft.AnimationCurve.BOUNCE_OUT,
duration=ft.Duration(seconds=5),
)
else:
tile.animation_style = ft.AnimationStyle.no_animation()
tile.update()
page.add(
ft.SafeArea(
content=ft.Column(
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
controls=[
ft.CupertinoSlidingSegmentedButton(
selected_index=0,
thumb_color=ft.Colors.BLUE_400,
on_change=switch_animation,
controls=[
ft.Text("Default animation"),
ft.Text("Custom animation"),
ft.Text("No animation"),
],
),
tile,
],
),
)
)
if __name__ == "__main__":
ft.run(main)
Theme mode toggle
import flet as ft
def main(page: ft.Page):
page.spacing = 0
page.padding = 0
def handle_switch_change(_: ft.Event[ft.Switch]):
if page.theme_mode == ft.ThemeMode.DARK:
page.theme_mode = ft.ThemeMode.LIGHT
switch.thumb_icon = ft.Icons.LIGHT_MODE
else:
switch.thumb_icon = ft.Icons.DARK_MODE
page.theme_mode = ft.ThemeMode.DARK
switch.update()
def handle_expansion_tile_change(e: ft.Event[ft.ExpansionTile]):
page.show_dialog(
ft.SnackBar(
duration=1000,
content=ft.Text(
value=(
f"ExpansionTile was "
f"{'expanded' if e.data == 'true' else 'collapsed'}"
)
),
)
)
if e.control.trailing:
e.control.trailing.icon = (
ft.Icons.ARROW_DROP_DOWN
if e.control.trailing.icon == ft.Icons.ARROW_DROP_DOWN_CIRCLE
else ft.Icons.ARROW_DROP_DOWN_CIRCLE
)
e.control.trailing.update()
switch = ft.Switch(thumb_icon=ft.Icons.DARK_MODE, on_change=handle_switch_change)
page.add(
ft.SafeArea(
content=ft.Column(
spacing=0,
controls=[
ft.ExpansionTile(
title=ft.Text("ExpansionTile 1"),
subtitle=ft.Text("Trailing expansion arrow icon"),
bgcolor=ft.Colors.BLUE_GREY_200,
collapsed_bgcolor=ft.Colors.BLUE_GREY_200,
affinity=ft.TileAffinity.PLATFORM,
maintain_state=True,
collapsed_text_color=ft.Colors.RED,
text_color=ft.Colors.RED,
controls=[
ft.ListTile(
title=ft.Text("This is sub-tile number 1"),
bgcolor=ft.Colors.BLUE_GREY_200,
)
],
),
ft.ExpansionTile(
title=ft.Text("ExpansionTile 2"),
subtitle=ft.Text("Custom expansion arrow icon"),
trailing=ft.Icon(ft.Icons.ARROW_DROP_DOWN),
collapsed_text_color=ft.Colors.GREEN,
text_color=ft.Colors.GREEN,
on_change=handle_expansion_tile_change,
controls=[
ft.ListTile(title=ft.Text("This is sub-tile number 2"))
],
),
ft.ExpansionTile(
title=ft.Text("ExpansionTile 3"),
subtitle=ft.Text("Leading expansion arrow icon"),
affinity=ft.TileAffinity.LEADING,
expanded=True,
collapsed_text_color=ft.Colors.BLUE_800,
text_color=ft.Colors.BLUE_200,
controls=[
ft.ListTile(title=ft.Text("This is sub-tile number 3")),
ft.ListTile(title=ft.Text("This is sub-tile number 4")),
ft.ListTile(title=ft.Text("This is sub-tile number 5")),
],
),
ft.Row(
expand=True,
alignment=ft.MainAxisAlignment.END,
controls=[
ft.Container(
padding=ft.Padding.only(bottom=50),
alignment=ft.Alignment.BOTTOM_RIGHT,
expand=True,
content=switch,
),
],
),
],
),
)
)
if __name__ == "__main__":
ft.run(main)