Sliding form steps in Flutter?

With an advice from a friend, I ended up using PageView. That way I didn't have to make a new route for every step.

class _RegisterFormState extends State<RegisterForm> {
  final _formsPageViewController = PageController();
  List _forms;


  @override
  Widget build(BuildContext context) {
    _forms = [
      WillPopScope(
        onWillPop: () => Future.sync(this.onWillPop),
        child: Step1Container(),
      ),
      WillPopScope(
        onWillPop: () => Future.sync(this.onWillPop),
        child: Step2Container(),
      ),
    ];

    return Expanded(
      child: PageView.builder(
        controller: _formsPageViewController,
        physics: NeverScrollableScrollPhysics(),
        itemBuilder: (BuildContext context, int index) {
          return _forms[index];
        },
      ),
    );
  }

  void _nextFormStep() {
    _formsPageViewController.nextPage(
      duration: Duration(milliseconds: 300),
      curve: Curves.ease,
    );
  }

  bool onWillPop() {
    if (_formsPageViewController.page.round() ==
        _formsPageViewController.initialPage) return true;

    _formsPageViewController.previousPage(
      duration: Duration(milliseconds: 300),
      curve: Curves.ease,
    );

    return false;
  }
}

Explanation:

  • I'm wrapping every form with WillPopScope so "back" button will affect navigation.
  • I'm using physics: NeverScrollableScrollPhysics() option on the PageView builder so it will not be affected by a swipe gesture.
  • On each button of a form step (except last step) I call the _nextFormStep() method, which moves to the next form.
  • The child of each WillPopScope() in the list is simply the form / widget you want to be slided.

Tags:

Dart

Flutter