B4A Library B4A - DeclarativeUI Library

Hi everyone,

After too many long power cuts, I apparently had the questionable idea of
writing a small declarative UI wrapper for B4A.

DeclarativeUI is an experiment inspired by Flutter and other modern UI
frameworks. It lets you describe a screen as a tree of widgets instead of
creating and positioning every native view manually.

For example::
Dim body As UIColumn
body.Initialize _
    .Spacing(12dip) _
    .AddChild(title) _
    .AddChild(description) _
    .AddChild(actionButton)

The library currently includes state binding, natural layout, themes,
navigation inside one Activity, dialogs, snackbars, animations and native
view interoperability.

It is not intended to replace B4A or B4X, and it is definitely not a complete
Flutter implementation. It is just a small beta project with rough edges,
created to explore whether this style of UI development feels useful in B4A.

Is it revolutionary? Probably not. Is it useful? Maybe.

I am sharing it mainly to get feedback. If you try it, I would be interested
in hearing what feels clear, what feels unnecessarily complicated and which
parts should be removed rather than expanded.

Purists may want to look away now.
 

Attachments

  • b4a-counter.zip
    7.7 KB · Views: 3
  • b4a-template.zip
    12.1 KB · Views: 3
  • DeclarativeUI.b4xlib
    88.2 KB · Views: 3
  • DeclarativeUI-ForumGuide.pdf
    58.3 KB · Views: 4

Mashiane

Expert
Licensed User
Longtime User
Hi

From someone who has been doing webdev in this forum forever and is now relearning everything about b4a I like this, a lot. I have always been fascinated by flutter and still believed that it can still be done with something like b4x without one having to learn dart, same with reactive native.

The State component is very interesting and I like the consistency you maintained when writing the components, the licensing is generous too. A personal thanks again for your contribution in this forum, Brilliant stuff. You are really here to change the world!

Q, Are you planning to make this fully cross platform?
Q, When can we see a fully working app? besides the two examples?
Q. Can you include more examples in the future, with screenshots please?

C. Just a heads up... something that I've also picked up when I was doing the B4XDaisyUIKit because I was so focused on UI creation with code too and are experiencing some layout issues here and there.

Building the layout programmatically -> using the designer when possible:
If you are only developing with B4A then building the layout programmatically is a mistake but not a huge one.
B4J and B4i handle screen resizes differently and it is much more difficult to handle the changes programmatically (there is video tutorial about it).
Most custom views can only be added with the designer (there are workarounds that allow adding them programmatically).
It is very simple to copy and paste designer layouts between different platforms and projects.

You will recall that there was a question previously about challenges experienced when creating long layouts or something.

That quote was sourced from...


All the best and keep up the good work you are doing!.
 

Mashiane

Expert
Licensed User
Longtime User
Counter example error... with b4a 13.50

B4X:
Unknown member: bottom
Unknown member: right
Unknown member: top
Unknown member: left
Unknown member: getcontentrect

B4X:
Error compiling program.
Error description: Unknown member: getcontentrect
Error occurred on line: 155
Dim contentRect As Rect = mIme.GetContentRect
Word: getcontentrect
 

Mashiane

Expert
Licensed User
Longtime User
So instead of getters and setters you use the "State" which does everything! Wow.

This seems like some kind of speed-demon framework.

Would be interesting to see benchmarks from normal b4x code, abstract designer and this. #Wishful thinking... ignore me on this, ha ha ha...

So the nova is multi-page app. pLease fix the error above otherwise I cant run.

I understand you are running the beta version of b4a with edege to edge. Not all of us are... ;)
 

Maxcfgos

Member
Licensed User
So instead of getters and setters you use the "State" which does everything! Wow.

This seems like some kind of speed-demon framework.

Would be interesting to see benchmarks from normal b4x code, abstract designer and this. #Wishful thinking... ignore me on this, ha ha ha...

So the nova is multi-page app. pLease fix the error above otherwise I cant run.

I understand you are running the beta version of b4a with edege to edge. Not all of us are... ;)
Thanks for such detailed feedback and the kind words!
  1. Please re-download the library
  2. Comment out this line: #EdgeToEdgeOldDevices: True
  3. You can ignore the warnings about the SDK and the logs — the IME library isn't needed for any B4A version anymore
  4. The examples should work fine now
Regarding the layout/measurements point: the library works similarly to Flutter, so since it's B4A-only it doesn't need manual measurements or the kind of cross-platform adjustments you mentioned.
  • I'm still not sure if I'll make it cross-platform
  • I'll be showing more complex/complete examples soon
 

Mashiane

Expert
Licensed User
Longtime User
My... the simplicity of your demos is amazing.

The fact that one is not thinking about Top, Left, Height, Width is so amazing. The Nova example pushed the bar.

So you didnt include images in your posts... I think you didnt do justice to your post. I would have, but then again its absolutely your choice.

It would be interesting to see this working with b4xpages.

The Nova Tasks is a simple app, large apps?

You have indeed brought flutter code styling to b4x.

1. The number in the first example needs padding, it clipped at the bottom.
2. The task descriptions could use multi-line if long, they wrap but clip.
3. Consider adding helpers e.g. VerticalAlignment, HorizontalAlignment.
4. Brilliant theming.
5. Redrawing the UI each time? e.g. theme changing... its not noticeable... might be expensive #just a thought.

Will be watching this attentively.
 

Mashiane

Expert
Licensed User
Longtime User
This is amazing... Did this just to get clarity on how this works... hope you dont mind. Im just still fascinated by this... 😍




 

Maxcfgos

Member
Licensed User
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:

example:
    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.
 

Maxcfgos

Member
Licensed User
Thing is, does it make the code readable and easy for beginners to follow for understanding & comprehension?
I completely understand your point. For someone coming from the imperative paradigm, the declarative approach can feel unnatural at first—even a bit cryptic. The initial learning curve is real: it takes time to get used to thinking about what you want to achieve rather than how to do it step by step.

However, once you get past that initial hurdle and start thinking in terms of data transformations, function composition, and expressions, the code becomes much cleaner, more predictable, and easier to reason about. What used to be loops and mutable state turns into clear statements of intent. And that's where the declarative paradigm truly shines: it reduces accidental complexity and makes code more maintainable and less error-prone.

In short: yes, it feels uncomfortable at first, but with a little practice, it becomes enormously simpler and more productive. It's like switching from a manual screwdriver to an electric one—it takes some getting used to at first, but once you do, you never want to go back.
 

Mashiane

Expert
Licensed User
Longtime User
User Manual - 💯, that answers my readability questions.

Checked the examples - love it!

UI.Text appears clipped at the bottom on my phone.

1787014839781.png


Brilliant Stuff!
 

Mashiane

Expert
Licensed User
Longtime User
The Nova Tasks is a simple app, large apps?
You are using a single activity for multiple pages, granted, this is how b4xpages does things anyway.

The code however to create the various screens in your example is in this same activity, being functions.

Q. Would you recomend a code module / class module where one wants to have separation of concerns?
Q. Is it possible for a kitchen sink app that will showcase all the components?
 
Top