Repository navigation
Releases
Releases · hotlayout/hotlayout-android
0.4.0
Reads document contract 9.33.0 (theme 4.0.1, icon set 1.0.0, data dictionary 1.8.0) and placement map 1.1.0. Folds in the entries that were prepared as 0.4.0 to 0.7.1 and never published (the last release is 0.3.0).
Added
- Placement schedule (placement map 1.1.0). A place may carry windows of time in which another document, or nothing
(a pause), stands in it instead of its permanent content.HotlayoutPlacementreads the place against the clock of
itsPlacementSource, sets a timer at the next boundary of the schedule (cut to 2^31 - 1 ms and counted again at its
end) and decides again there, on every new reading of the map, and when the app returns to the foreground; the map
is not asked again at a boundary.loadPlacementreads the place at the same clock.PlacementSourcehas a new last
parameterclock: () -> Long(milliseconds since the epoch; the device clock by default) to pin time in tests. A
broken window is skipped on its own, a pause never reads its entry, overlapping windows go to the one that started
later. Every row of thescheduleCasesgroup ofplacements/placement-cases.jsonis run. The README shows how a
host hides its own padding around a place that is empty. - A place with a schedule shows its window on time and with no network. After the first decision of a place,
PlacementSourcereads in the background the documents of every window of the schedule and keeps them in its
store (at most 64 documents; the oldest copy is dropped first). A failed reading keeps the last good copy, a 404
drops it, and deciding the place again at a boundary or on return to the foreground while offline does not blank the
document that stands there. - A node that fades in and out when its condition changes. A node with
visibilityTransition: fadeand a
visibleIfno longer appears and disappears at once: a node whose condition stops holding keeps its place and
fades out in 120 ms, then leaves the layout; a node whose condition starts to hold waits 120 ms out of the layout,
then enters it transparent and fades in over 160 ms. There is no pairing: every node follows its own timeline, so
two neighbours with exclusive conditions change the layout once, when both are invisible. A change in the middle of
a transition goes to the new goal from the current opacity, the time scaled by the distance; a node still waiting
stays hidden. A fading-out node catches no press and is not heard by the screen reader; a fading-in node is a
control from the moment it enters the layout. The durations and curves are the data of the contract. - Everything else stays at once: the first show of a screen, going back to a screen, a change of the language or of
the width class, a change under a covered screen, and a system whose animation scale is zero. The zones of the
screen follow the condition at once and do not read the field: a node withpin(bottom or top), aNavBar, a
NavItemand anAppBarthat is the first child of the screen root; anAppBaranywhere else fades like any node. - A carousel that tells its active stop. The optional
carousel.stopPathnames a number path of the data
dictionary; its value is the number of the snap stop from 0 (stops, not cards). After a person's swipe has settled
on a stop the reader writes that number to the path, the very write an input field makes (the session of the
screen andonWriteof the host at the same moment, underwritablePaths). It writes only for a move by a
person (a finger, the wheel, a key), never while the finger still holds the row, never for a move the reader made
itself, and never the same number again. When the carousel is shown it stands on the stop the value names
without animation (a number clamped to the stops; a fraction, a text or no value is the first stop), and it moves
to that stop when the number the value names changes, not while a finger holds the row. A write the host refused
leaves the carousel where the person put it. A pointer that was cancelled counts as released. A path on a row
that does not scroll, an empty one, one longer than 128 characters or one that is not a string is no path: the
carousel then scrolls as before and writes nothing. - The bottom safe inset of a modal sheet. A layer shown as a sheet (
presentation: modal, nomodalPlacementor
bottom, in a compact area) still reaches the bottom of its area, and the reader now adds the navigation bar
inset (or thesafeAreaBottomthe host passed) inside the box of the sheet, under its content: the background and
the radius of the root extend under the gesture bar, the last node stands above it. The inset is added once: with
a shown pinned block it goes under the content of that zone, without one it is the bottom padding of the root.
The height of the sheet is its content plus the inset, no taller than the area; taller content scrolls above the
inset. While the keyboard is shown the sheet rises above it and adds nothing. A window (center), a sheet shown
as a window in a wider area and a page are unchanged, and a host that passes zero gets zero. - A write action on a long press. A node whose own action does not write may carry
setValueortoggleValuein
longPress; the hold (also Shift+F10 and the named action of a screen reader) performs it through the same write as
a pressed action: the haptic request and the analytics event go first, then the write into the session and
onWrite(underwritablePaths), and a value already held is not written again. The role of the node still
comes fromactionalone, so the node stays a plain button. Before, a write action on a long press was ignored. - The node field
name(a label for the editor) is accepted and ignored: it is not drawn, not part of an accessible
name and not passed to actions, events or reports.
Fixed
- A carousel that tells its stop follows the LAST value when the host changes it twice in a row while the first
animation is still running. Following compared the new number with the stop the animation was passing and
took it for "already there", so the carousel stayed where the cancelled move had been. "Where the carousel is"
is now the target of the reader's own move until that move has settled (a person's touch, wheel or key
clears it). - A row of a list from data fades too. When the template of a
RepeaterhasvisibilityTransition: fadeand a
condition on the fields of the record, every row follows its own timeline (the key is the node and the indexes of
the template instances it stands in): a row whose condition stops holding fades out in place and the rows around
it do not move until it has left.