Sliding form steps in Flutter? Sliding form steps in Flutter? flutter flutter

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 willaffect 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.


as an option you can wrap pages with Navigator widgetsomething like this

import 'package:flutter/cupertino.dart';import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {  @override  Widget build(BuildContext context) {    final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();    return MaterialApp(      home: Scaffold(        appBar: AppBar(title: Text('Title')),        body: SafeArea(          child: WillPopScope(            onWillPop: () async => !await _navigatorKey.currentState.maybePop(),            child: Navigator(              key: _navigatorKey,              onGenerateRoute: (settings) {                switch (settings.name) {                  case '/':                    return MaterialPageRoute(builder: (context) => HomePage());                    break;                  case '/step1':                    return CupertinoPageRoute(builder: (context) => FormStep1());                    break;                  case '/step2':                    return CupertinoPageRoute(builder: (context) => FormStep2());                    break;                }              },            ),          ),        ),      ),    );  }}class HomePage extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Container(      color: Colors.green[200],      child: Column(        mainAxisAlignment: MainAxisAlignment.center,        children: <Widget>[          Text('HomePage'),          RaisedButton(            onPressed: () => Navigator.pushNamed(context, '/step1'),            child: Text('Start'),          ),        ],      ),    );  }}class FormStep1 extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Container(      color: Colors.blue[200],      child: Column(        mainAxisAlignment: MainAxisAlignment.center,        children: <Widget>[          Text('FormStep1'),          RaisedButton(            onPressed: () => Navigator.pushNamed(context, '/step2'),            child: Text('Next'),          ),        ],      ),    );  }}class FormStep2 extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Container(      color: Colors.yellow[200],      child: Column(        mainAxisAlignment: MainAxisAlignment.center,        children: <Widget>[          Text('FormStep2'),          RaisedButton(onPressed: () {}, child: Text('Next')),        ],      ),    );  }}

enter image description here

also instead of CupertinoPageRoute you can use any custom Route with any transition