fluorflow

Last updated:

0 purchases

fluorflow Image
fluorflow Images
Add to Cart

Description:

fluorflow

FluorFlow #
FluorFlow is a dart / flutter package for
MVVM UI architecture.
It is heavily inspired by Stacked.
Getting started #
After adding the package to your pubspec.yaml file, you can start using it by
modifying your main.dart file as follows:
void main() async {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'FluorFlow Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// This is the important part for routing
initialRoute: AppRoute.homeView.path,
onGenerateRoute: onGenerateRoute,
navigatorKey: NavigationService.navigatorKey,
navigatorObservers: [NavigationService.observer],
);
}
}
copied to clipboard
Especially the part for routing is important (if you use FluorFlow views and routing):
initialRoute: AppRoute.homeView.path,
onGenerateRoute: onGenerateRoute,
navigatorKey: NavigationService.navigatorKey,
navigatorObservers: [NavigationService.observer],
copied to clipboard
This enables the routing system of FluorFlow.
The other parts of the app can be as you wish.
Views #
Creating views with view models has the advantage that you can separate the business logic
from the presentation of the view itself. This makes the code more readable and maintainable.
Further, you can just test your view models without the need of a UI test.
If UI testing is still needed, you can just fire up the whole view and test the UI anyway.
However, most of the time the business logic is the most important part of the app and should
be tested well.
To create a view with a view model, you can use the following example code:
final class HomeViewModel extends BaseViewModel {
final _navService = locator<NavigationService>();

var _counter = 0;
int get counter => _counter;

void increment() {
_counter++;
notifyListeners();
}

void goToDetail() => _navService.navigateToDetailView();
}

@Routable()
final class HomeView extends FluorFlowView<HomeViewModel> {
const HomeView({super.key});

@override
Widget builder(
BuildContext context, HomeViewModel viewModel, Widget? child) =>
Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: Center(
child: const Text('Show Dialog'),
),
);

@override
HomeViewModel viewModelBuilder(BuildContext context) => HomeViewModel();
}
copied to clipboard
The @Routable annotation is important for the routing system of FluorFlow. It is used to
generate the AppRoute enum and create extension methods on the NavigationService.
Dependency Injection #
FluorFlow uses the get_it package for dependency injection.
In combination with the FluorFlow generator, you can easily inject your dependencies in a
setupLocator method and use them in your app.
The following example assumes that you use the fluorflow_generator (with build_runner)
to generate the app.locator.dart file.
// service.dart

@LazySingleton()
class Service {
// implementation
}

// main.dart
import 'app.locator.dart';

void main() async {
await setupLocator();
runApp(const MyApp());
}
copied to clipboard
In your app, you can then use the provided locator via:
import 'package:fluorflow/fluorflow.dart';

final svc = locator<Service>();
//...
copied to clipboard
There are several possible types of injection:

Singleton
LazySingleton
AsyncSingleton
Factory (with up to two parameters)
CustomLocatorFunction (for custom injection and functions)

Dialogs / Bottom Sheets #
A bottom sheet can be created with or without a view model.
The simple variant just defaults to a internal NoopViewModel that has no
further methods attached.
An example of a bottom sheet is:
final class GreetingBottomSheet extends FluorFlowSimpleBottomSheet<void> {
const GreetingBottomSheet({super.key, required super.completer});

@override
Widget build(BuildContext context) => Scaffold(
backgroundColor: Colors.amber[200],
appBar: AppBar(
title: const Text('Bottom Sheet'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('A Bottom Sheet'),
const SizedBox(height: 36),
ElevatedButton(
onPressed: completer.confirm,
child: const Text('Close'),
),
],
),
),
);
}
copied to clipboard
Bottom sheets are shown via the NavigationService that has extension methods
attached for each bottom sheet. Parameters of sheets are taken into account
when used with the fluorflow generator.
Dialogs work exactly the same way as bottom sheets, but are shown via the
Dialogs extension in the NavigationService and have another base class.
Important: Bottom sheets are always wrapped in a Scaffold widget. Thus,
they inherit your styles. Dialogs do not have this behavior (by design).
So you may create a full screen dialog and wrap it in a Scaffold, or
if you want a small "modal dialog" that has a backdrop and is dismissible
on click of the backdrop, it is also possible. However, you need
to wrap some parts of the content into a Material (or Theme provider)
widget to provide some decent default styles. Otherwise, some styles
are weird (e.g. Text Styles are big, red, and underlined).
You can see this in the examples (SmallDialog).
CLI #
FluorFlow comes with a CLI that can be used to generate views and other things.
Use dart run fluorflow to see the available commands.
To change configuration of the CLI (especially the biased options of the generator),
use the fluorflow key in your pubspec.yaml file.
fluorflow:
view_directory: lib/my_views
test_view_directory: test/my_views
copied to clipboard
Defaults are:

view_directory: lib/ui/views
test_view_directory: test/ui/views

License:

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.