On Maven Central:
implementation("io.github.diffechento:metro:1.0.1")Additive only. Every change here is a new parameter with a default or a new declaration, so a call
written against 1.0.0 compiles unchanged — the acceptance test is :sample building untouched, which
it does.
A long list can be arranged by anything, not only by its initial letter. MetroListSort is that
arrangement as data — a name, a comparator, and what the header above each run of rows says — so a
screen can hold several and hand the list whichever is in force. MetroListSort.alphabetical is the
A–Z one this list has always had, spelled that way so it can sit in a menu beside "by date added".
- A group header is a label, not a character: one character is the letter tile as before, a word
("july 2026", "10+ plays") keeps its height and grows sideways at a smaller size, and an empty label
draws no header at all. - Groups are runs of consecutive rows sharing a label, so a header that disagrees with its
comparator shows a repeated heading rather than quietly reordering rows behind your back. - Every arrangement zooms out. A tap on a header still opens the whole set of groups over the
screen and jumps to the one picked. Letters keep the phone's grid of squares; words become a column
of blocks the width of their own text, and it scrolls, because four years of listening is fifty
months of headings. jumpDomainanswers with the whole domain given the labels present, and the empty ones are drawn
dimmed and inert. Null — the default — means the groups themselves, which is the right answer when
the domain is open-ended: there is no set of all months.- Pass
sortsand a hold on a header unrolls them out of that header, via the same
MetroContextMenua held row gets.
A header can roll away with the list under it — MetroCollapse, Modifier.metroCollapsingHeader,
Modifier.metroCollapseOnScroll. It gives up its height, so what follows moves up and grows into the
space rather than being covered by it. The header goes first and comes back last, a fling that reaches
the top of the list carries on into the header, and whatever contains it has to clip — the modifier
clips nothing itself.
The panorama spends 68dp less on its own title. Measured on a 1080x2400 screen, a section's first
row started 788px down and now starts at 609px: the status bar is cleared by inset rather than by a
hand-picked 52dp, the blank the font reserves above the capitals and below the baseline is trimmed
(30dp and 16dp at 108sp — by shortening the layout, not by lineHeight, which cannot touch ascent and
descent), includeFontPadding = false, and the two gaps are 6dp and 12dp. titleTopPadding, titleGap
and headerGap are parameters if you want the air back.
A top banner no longer swallows the screen while it is up. It lived in a screen-sized popup, so for
the two seconds a banner showed, every tap went into a transparent window and nothing underneath
answered. The popup is now the size of the banner and the window is what slides in.
Also: MetroContextMenu takes selectedItem and draws that entry in accent, its sheet is slightly
translucent (sheetAlpha) and as wide as its widest label but never narrower than the anchor, and the
zoom-out is translucent too, so it reads as the same page pulled back rather than a different screen.
:sample's collection screen now offers three arrangements of the same forty artists — by name, by
plays and by date added — so the letters, the closed set of bands and the open-ended months are all on
screen rather than described.
Full details, with the reasoning, in CHANGELOG.md.