Skip to content

Components and layouts

Text, buttons and inputs

title = label("Library", variant="headline", screen=home)

search = inputs(
    "Search tracks",
    type="search",
    on_change=lambda query: filter_tracks(query),
    screen=home,
)

button(
    "Continue",
    variant="filled",
    icon="arrow_forward",
    command=open_library,
    screen=home,
)

Button variants are filled, outlined, tonal, text, danger and icon.

Input types include text, password, search, number, textarea, select, switch, checkbox, range, radio, date and time.

Containers and composition

panel = container(id="panel", screen=home)
label("Account", variant="title", parent=panel)
inputs("Email", type="text", parent=panel)
button("Save", variant="filled", parent=panel)

Style the parent to control its children:

panel {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 18px;
    background-color: var(--surface);
    border-radius: var(--radius);
}

Cards

Use a ready-made semantic card:

from apkpy_lib import card, card_action

premium = card(
    title="Premium",
    subtitle="Offline listening and high-quality audio",
    image="headphones.jpg",
    content="Available across your signed-in devices.",
    actions=[
        card_action("Learn more", variant="text", command=show_details),
        card_action("Try it", variant="filled", command=start_trial),
    ],
    variant="elevated",
    screen=home,
)

Or compose any supported child manually:

custom = card(id="custom_card", variant="outlined", screen=home)
label("Custom content", variant="title", parent=custom)
button("Open", variant="text", parent=custom)

Lists

Plain and rich rows use the same list_view:

tracks = list_view(
    [
        {
            "title": "Midnight Drive",
            "subtitle": "Nova",
            "image": "cover.jpg",
            "src": "track.mp3",
        }
    ],
    rich=True,
    on_click=lambda item: audio.play_background(
        item["src"],
        title=item["title"],
        artist=item["subtitle"],
        art=item["image"],
    ),
    screen=home,
)

Update it later:

tracks.set_items(new_items)

Database and HTTP JSON can be mapped directly:

rows = db.query("SELECT title, artist FROM tracks ORDER BY title")
tracks.set_items(rows, title="title", subtitle="artist")

Carousels and grids

carousel(albums, on_click=open_album, screen=home)
grid(categories, cols=2, on_click=open_category, screen=home)

Rich items can contain title, subtitle, image and application-specific fields such as src.

Responsive layouts

Describe how the same component tree rearranges:

profile_panel = container(id="profile_panel")
details_panel = container(id="details_panel")

responsive(
    mobile=column(profile_panel, details_panel),
    tablet=row(profile_panel, details_panel),
    breakpoint=600,
    screen=home,
)

The Android build chooses the appropriate layout for the available width. In the Previewer:

device("responsive")

Resize the window to test the breakpoint.

CSS flex and grid

ApkPy supports the layout properties needed for application interfaces, including:

  • display, flex-direction, flex-wrap and gap;
  • justify-content, align-items and align-self;
  • flex-grow, flex-shrink and flex-basis;
  • grid columns/rows, spans and gaps;
  • width, height, min/max sizes, margins and padding;
  • relative/absolute positioning, offsets and z-index.

Use responsive composition for major structural changes and CSS for sizing/alignment inside a structure.