Library update v0.6
THE COUNTER IS INSANE
The canonical example (examples/b4a_declarative_counter) takes code reduction
to the extreme: the entire screen (app bar with theme action, bound label,
FAB, centered column) is ONE single expression, 13 lines:
Code:
Screen = UI.Scaffold(UI.Center(UI.Column(Null) _
.Spacing(12dip).MainAxisAlignment("center").CrossAxisAlignment("stretch") _
.AddChild(UI.Text("You have pushed the button this many times:") _
.Size(AppTheme.BodyLarge).Color(AppTheme.SecondaryText)) _
.AddChild(UI.Text("").BindText(CounterState) _
.Size(52).Color(AppTheme.PrimaryText)))) _
.AppBar(UI.AppBar("Declarative Counter") _
.Action(UI.IconFA(Chr(IIf(AppTheme.IsDark, 0xF185, 0xF186))).Size(24) _
.Color(AppTheme.DashboardBarText).OnClick(Me, "ToggleTheme_Click"))) _
.FloatingActionButtonRight(UI.Fab("+") _
.OnClick(Me, "Increment_Click")) _
.ApplyTheme(AppTheme)
UI.Show(Root, Screen)
No Dim + Initialize, no SetParent/SetPosition/SetSize by hand: UI.Show mounts
everything. The whole Activity (counter + theme + buttons) is 68 lines, most
of them project attributes.
A TRUE WIDGET TREE
The code is no longer a list of AddView calls: it is a real hierarchical
composition (Scaffold > Column > Text > bindings...). Every widget has a
lifecycle (SetParent/SetPosition/SetSize/Render/Detach/Unmount) and natural
measurement; containers (Column/Row/Stack) own the layout of their children.
New in 0.6:
- UIButton renders FontAwesome glyphs in its text (U+F000..U+F8FF) with the
correct typeface: UI.Button(Chr(0xF04B) & " Run") = play icon + label, no
extra API.
- Automatic safe area in UIScaffold (WindowInsets, zero per-screen code).
- Automatic re-layout of bound widgets (a label grows from "9" to "10"
without clipping).
- One-way bindings with precedence: the static setter cancels the binding.
- UIState/UIAsyncState, Material 3 themes, snackbars, dialogs, animations,
virtualized UIListView with pooling, virtual navigation inside one Activity.
No longer a demo
Feedback, bugs and ideas are welcome.