Write cross-platform apps with Xamarin.Forms, using MVU architecture and dynamic UI
Never write a ViewModel class again! Conquer the world with clean dynamic UIs!
This library allows you to use the ultra-simple Model-View-Update architecture to build applications for iOS, Android, Mac, WPF and more using Xamarin.Forms. It is built on Fabulous.
The amount of code I’m not writing is great! @jimbobbennett
Note that this is just a “Getting Started” page for Fabulous. For detailed guides to different parts of the library, please visit the respective pages via the links below:
- Overview
- Getting started
- Views
- Models
- Update and Messages
- Traces and Crashes
- Unit testing
- Tools
- Pitfalls and F# 5.0 support
- Migration guide from v0.57 to v0.60
- Further Resources
- They use Fabulous
Getting started
-
Install Visual Studio or Visual Studio for Mac and enable both Xamarin and .NET Core support, these are listed as ‘Mobile development with .NET’ and ‘.NET Core Cross-platform development’ respectively.
-
Open a command prompt window and install the template pack by entering:
dotnet new -i Fabulous.XamarinForms.Templates
-
Navigate to a folder in the command prompt window where your new app can be created and enter:
dotnet new fabulous-xf-app -n SqueakyApp
-
Open, edit and build in Visual Studio or Visual Studio for Mac
SqueakyApp/SqueakyApp.sln
-
Before deploying and running, first connect and enable your device, choose between iOS (Emulator, Device) or Android (Emulator, Device).
-
To run, set either your Android or iOS project as the startup project, then use F5.
By default iOS and Android projects are created. But you can also target WPF with --WPF
, UWP with --UWP
, macOS with --macOS
and/or GTK with --GTK
. Here some common examples, but feel free to change the targets to the ones you require:
Android only:
dotnet new fabulous-xf-app -n SqueakyApp --iOS=false
iOS only:
dotnet new fabulous-xf-app -n SqueakyApp --Android=false
WPF only:
dotnet new fabulous-xf-app -n SqueakyApp --WPF --Android=false --iOS=false
UWP only:
dotnet new fabulous-xf-app -n SqueakyApp --UWP --Android=false --iOS=false
macOS only:
dotnet new fabulous-xf-app -n SqueakyApp --macOS --Android=false --iOS=false
GTK only:
dotnet new fabulous-xf-app -n SqueakyApp --GTK --Android=false --iOS=false
All 6 platforms:
dotnet new fabulous-xf-app -n SqueakyApp --WPF --UWP --macOS --GTK
-
If you are using Visual Studio for Mac and you want to start with
File -> New
, make sure you target “.NET Standard” to add the references to Fabulous:File -> New Solution Multiplatform App -> Blank Forms App (F#) Shared Code -> Use .NET Standard
A Basic Example
Here is a full example of an app:
open Fabulous
open Fabulous.XamarinForms
open Xamarin.Forms
/// The messages dispatched by the view
type Msg =
| Pressed
/// The model from which the view is generated
type Model =
{ Pressed: bool }
/// Returns the initial state
let init() = { Pressed = false }
/// The function to update the view
let update (msg: Msg) (model: Model) =
match msg with
| Pressed -> { model with Pressed = true }
/// The view function giving updated content for the page
let view (model: Model) dispatch =
View.ContentPage(
content=View.StackLayout(
children=[
if model.Pressed then
yield View.Label(text="I was pressed!")
else
yield View.Button(text="Press Me!", command=(fun () -> dispatch Pressed))
]
)
)
type App () as app =
inherit Application ()
let runner =
Program.mkSimple init update view
|> Program.withConsoleTrace
|> XamarinFormsProgram.run app
The init function returns your initial state, and each model gets an update function for message processing. The view
function computes an immutable Xaml-like description. In the above example, the choice between a label and button depends on the model.Pressed
value.
Some advantages of using an immutable model are:
- It is easy to unit test your
init
,update
andview
functions - You can save/restore your model relatively easily
- It makes tracing causality usually very simple
Samples
The sample CounterApp contains a slightly larger example of Button/Label/Slider elements.
The sample TicTacToe contains examples of the Grid and Image elements.
The sample AllControls contains examples of instantiating most elements in Xamarin.Forms.Core
.
The sample Calculator (original external sample) is a small calculator app.
The external sample PocketPiggyBank is a small client-server app with login authentication. (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)
The external sample FabulousContacts is a multi-page contacts app featuring maps, group-lists and cross-page messages. (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)
The external sample FabulousPlanets is a multi-page app featuring facts on the planets in the Solar System. It uses Urho3D and Fabulous (Note: because this is an external sample it may not be up-to-date with the latest version of this library.)
The external sample Fabulous + GraphQL Type Provider is a small app that demonstrates how to use the type provider for GraphQL FSharp.Data.GraphQL.
See also the curated list Awesome Fabulous.
Further Resources
Presentation: Making Mobile App Development Simple with F#
Presentation: Building mobile apps with F# using Xamarin - Jim Bennett - Xamarin University Guest Lecture
General Docs
Android Setup
iOS Setup
Contributing
Please contribute to this library through issue reports, pull requests, code reviews and discussion.