flutter flows made easy!
usage
define a flow state
the flow state will be the state which drives the flow. each time this state changes, a new navigation stack will be generated based on the new flow state.
class profile {
const profile({this.name, this.age, this.weight});
final string? name;
final int? age;
final int? weight;
profile copywith({string? name, int? age, int? weight}) {
return profile(
name: name ?? this.name,
age: age ?? this.age,
weight: weight ?? this.weight,
);
}
}
create a flowbuilder
flowbuilder
is a widget which builds a navigation stack in response to changes in the flow state. ongeneratepages
will be invoked for each state change and must return the new navigation stack as a list of pages.
flowbuilder<profile>(
state: const profile(),
ongeneratepages: (profile, pages) {
return [
materialpage(child: nameform()),
if (profile.name != null) materialpage(child: ageform()),
];
},
);
update the flow state
the state of the flow can be updated via context.flow<t>().update
.
class nameform extends statefulwidget {
@override
_nameformstate createstate() => _nameformstate();
}
class _nameformstate extends state<nameform> {
var _name = '';
void _continuepressed() {
context.flow<profile>().update((profile) => profile.copywith(name: _name));
}
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(title: const text('name')),
body: center(
child: column(
children: <widget>[
textfield(
onchanged: (value) => setstate(() => _name = value),
decoration: inputdecoration(
labeltext: 'name',
hinttext: 'john doe',
),
),
raisedbutton(
child: const text('continue'),
onpressed: _name.isnotempty ? _continuepressed : null,
)
],
),
),
);
}
}
complete the flow
the flow can be completed via context.flow<t>().complete
.
class ageform extends statefulwidget {
@override
_ageformstate createstate() => _ageformstate();
}
class _ageformstate extends state<ageform> {
int? _age;
void _continuepressed() {
context
.flow<profile>()
.complete((profile) => profile.copywith(age: _age));
}
@override
widget build(buildcontext context) {
return scaffold(
appbar: appbar(title: const text('age')),
body: center(
child: column(
children: <widget>[
textfield(
onchanged: (value) => setstate(() => _age = int.parse(value)),
decoration: inputdecoration(
labeltext: 'age',
hinttext: '42',
),
keyboardtype: textinputtype.number,
),
raisedbutton(
child: const text('continue'),
onpressed: _age != null ? _continuepressed : null,
)
],
),
),
);
}
}
flowcontroller
a flowbuilder
can also be created with a custom flowcontroller
in cases where the flow can be manipulated outside of the sub-tree.
class myflow extends statefulwidget {
@override
state<myflow> createstate() => _myflowstate();
}
class _myflowstate extends state<myflow> {
late flowcontroller<profile> _controller;
@override
void initstate() {
super.initstate();
_controller = flowcontroller(const profile());
}
@override
widget build(buildcontext context) {
return flowbuilder(
controller: _controller,
ongeneratepages: ...,
);
}
@override dispose() {
_controller.dispose();
super.dispose();
}
}
Comments are closed.