-
Notifications
You must be signed in to change notification settings - Fork 3
Views
A view is a collection of visible elements that receives user inputs.
This is a StatefulWidget that creates a view model and provides it to its child widgets. It requires a create function to create the view model and a builder function to build the UI based on the view model.
Given the following view model:
class HomeViewModel extends ViewModel {
final ValueNotifier<int> _count = ValueNotifier(0);
ValueListenable<int> get count => _count;
void increment() => _count.value++;
}
We can use ViewModelBuilder
to create the view model and build the UI:
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelBuilder<HomeViewModel>(
create: (BuildContext context) => HomeViewModel(),
builder: (BuildContext context, HomeViewModel viewModel) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Text('Count value: ${viewModel.count}'),
floatingActionButton: FloatingActionButton(
onPressed: viewModel.increment,
child: const Icon(Icons.add),
),
);
},
);
}
}
-
create
is a function that creates the view model, and it is called only once. You can use other ways of creating the view model, such as using a service locator. -
builder
is a function that builds the UI based on the view model. It is called initially, and is called again when the framework notifies the widget to rebuild. -
onDispose
is a function that is called when the widget is removed from the tree. You can use it to clean up resources.
This is a StatelessWidget that automatically builds a view model and provides it to its child widgets. It uses a ViewModelBuilder
to create the view model and a ServiceLocator
to get an instance of the view model.
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AutoViewModelBuilder<HomeViewModel>(
builder: (BuildContext context, HomeViewModel viewModel) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Text('Count value: ${viewModel.count}'),
floatingActionButton: FloatingActionButton(
onPressed: viewModel.increment,
child: const Icon(Icons.add),
),
);
},
);
}
}
-
onCreate
is a function that is called when the view model is created. You can use it for additional initialization. -
builder
is a function that builds the UI based on the view model. It is called initially, and is called again when the framework notifies the widget to rebuild. -
onDispose
is a function that is called when the widget is removed from the tree. You can use it to clean up resources.
You can access the view model using ViewModelProvider.of<T>(context)
or context.viewModel<T>()
. This looks up the nearest ancestor ViewModelProvider
widget and returns the view model.
class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ViewModelBuilder<HomeViewModel>(
create: (BuildContext context) => HomeViewModel(),
child: const Scaffold(
appBar: AppBar(title: Text('Home')),
body: _Counter(),
floatingActionButton: _CounterButton(),
),
);
}
}
class _Counter extends StatelessWidget {
const _Counter();
@override
Widget build(BuildContext context) {
return Text('Count value: ${context.viewModel<HomeViewModel>().count}');
// or
return Text('Count value: ${ViewModelProvider.of<HomeViewModel>(context).count}');
}
}
class _CounterButton extends StatelessWidget {
const _CounterButton();
@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: context.viewModel<HomeViewModel>().increment,
// or
onPressed: ViewModelProvider.of<HomeViewModel>(context).increment,
child: const Icon(Icons.add),
);
}
}
💡 TIP
- This can be used if you want to breakdown your UI into smaller widgets and still have access to the view model.
- You can replace the
builder
parameter with achild
parameter since we are not using the view model in the builder function.