Guides
Overriding Component UI
This is an exploration of overriding a component's UI within Flutter Forge.
There are two main methods of overriding a component's UI within Flutter Forge.
- the optional
builder
constructor parameter - inherit from the component and override the
build
method
Optional builder
parameter
This is probably the more idiomatic approach in the Flutter community. But if you don't like it for some reason you can always use the "Inherit & Override" approach.
// defined somewhere up the hierarchy (possibly even globally)
counterStore = Store(
initialState: const CounterState(count: 0),
reducer: counterReducer,
environment: CounterEnvironment(),
);
Counter(
store: counterStore,
builder: (context, store, viewStore) {
return Column(children: [
Rebuilder(
store: store,
builder: (context, state, child) {
return Text(
'${state.count}',
style: Theme.of(context).textTheme.displayLarge,
);
}),
ElevatedButton(
onPressed: () => viewStore
.send(counter.CounterIncrementButtonTapped()),
child: const Text("overriden ui - increment"))
]);
}),
In this example we simply construct an instance of the Counter
component while providing the optional builder
function which if present is responsible for returning the widget tree for that component. Allowing you to override the UI of the component.
Note: When people define their components. They need to make sure that they proxy the builder
parameter through the constructor otherwise this option won't be available to consumers of their components.
class Counter
extends ComponentWidget<CounterState, CounterEnvironment, CounterAction> {
const Counter({super.key, required super.store, super.builder});
In the above we can see that we are passing the two optional parameters key
& builder
through to the base class by using super.key
& super.builder
respectively.
Inherit & Override build
In the following example we simply create a class called CounterWithOverridenUi
that extends
from Counter
and @override
the build
method.
class CounterWithOverridenUi extends Counter {
CounterWithOverridenUi({super.key, required super.store, super.builder});
@override
Widget build(context, viewStore) {
return Column(children: [
Rebuilder(
store: store,
builder: (context, state, child) {
return Text(
'${state.count}',
style: Theme.of(context).textTheme.displayLarge,
);
}),
ElevatedButton(
onPressed: () =>
viewStore.send(counter.CounterIncrementButtonTapped()),
child: const Text("overriden ui - increment"))
]);
}
}
This makes it so that CounterWithOverridenUi
is a component of the same CounterState
, CounterEnvironment
, and CounterAction
that the Counter
widget is. But it uses the overridden build
method for the UI rather than the build
method provided by the Counter
widget.