Stepper content Widget

You might have an application form that need to split in some steps, which consist so many field in one form and you need to split them into some steps, in order to solve that problem you need to add Stepper widget into your apps, but the next problem is how to split forms widget and stepper widget. So here we will learn how to create Stepper Widget and call widget from another file and wrap to Stepper Widget.

Table of Contents

Introduction

Stepper is material stepper widget from Flutter that displays progress through a sequence of steps. Steppers are particularly useful in the case of forms where one step requires the completion of another one, or where multiple steps need to be completed in order to submit the whole form.

The widget is a flexible wrapper. A parent class should pass currentStep to this widget based on some logic triggered by the three callbacks that it provides.

Learn more about Stepper Class here.

In this article we will learn how to use stepper with content widget inside step.  

Let’s get started

Stepper View

Create new project flutter and create file StepperView.dart inside lib folder. first we should to declare List Step as collection of every steps.

int currentStep = 0;
  List<Step> spr = <Step>[];
  List<Step> _getSteps() {
    spr = <Step>[
      Step(
        state: _getState(1),
        title: Text("Step 1"),
        content: new Wrap(
          children:<Widget>[
            StepOneView()
          ],
        ),
        isActive: (currentStep == 0 ? true : false)
      ),
      Step(
        title: Text("Step 2"),
        content: new Wrap(
          children:<Widget>[
            StepTwoView()
            ],
        ),
        isActive: (currentStep == 1 ? true : false),
        state: _getState(2),
      )
    ];
    return spr;
  }

  StepState _getState(int i) {
    if (currentStep >= i)
      return StepState.complete;
    else
      return StepState.indexed;
  }

We have 2 step inside there, if you want to add more step you can add in there, in step 1 inside the content we have widget Wrap to call Form widget in class StepOneView and in step 2 we call ListView widget in class StepTwoView inside Wrap.

And we also need to declare _getState for handle next step when user click next or continue from step.

next we add Stepper widget

Widget _typeStep() => Container(
    child: Stepper(
      
      controlsBuilder: (BuildContext context, {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
        return Padding(
          padding: EdgeInsets.all(8.0),
          child: RaisedButton(
            onPressed: () {
              setState(() {
                currentStep < spr.length - 1 ? currentStep += 1 : currentStep = 0;
              });
            },
            color: Colors.blue,
            textColor: Colors.white,
            child: Text('Next'),
          ),
        );
      },
      
      steps: _getSteps(),
      currentStep: currentStep,
      type: StepperType.horizontal,
      onStepTapped: (step) {
        setState(() {
          currentStep = step;
          print(step);
        });
      },
      onStepCancel: () {
        setState(() {
          currentStep > 0 ? currentStep -= 1 : currentStep = 0;
        });
      },
      onStepContinue: () {
        setState(() {
          currentStep < spr.length - 1 ? currentStep += 1 : currentStep = 0;
        });
      },
    ),
  );

In that Stepper we call list step in steps, and we also have event onStepContinue for handle jump to the next step. And next we call Stepper widget into build, here is full code StepperView.dart

import 'package:flutter/material.dart';
import 'package:stepper_content_widget/StepOneView.dart';
import 'package:stepper_content_widget/StepTwoView.dart';


class StepperView extends StatefulWidget {
  StepperView({Key key}) : super(key: key);
  
  @override
  _StepperViewState createState() => new _StepperViewState();
}

class _StepperViewState extends State<StepperView> {
  
  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        _typeStep(),
      ],
    );
  }

  int currentStep = 0;
  List<Step> spr = <Step>[];
  List<Step> _getSteps() {
    spr = <Step>[
      Step(
        state: _getState(1),
        title: Text("Step 1"),
        content: new Wrap(
          children:<Widget>[
            StepOneView()
          ],
        ),
        isActive: (currentStep == 0 ? true : false)
      ),
      Step(
        title: Text("Step 2"),
        content: new Wrap(
          children:<Widget>[
            StepTwoView()
            ],
        ),
        isActive: (currentStep == 1 ? true : false),
        state: _getState(2),
      )
    ];
    return spr;
  }

  StepState _getState(int i) {
    if (currentStep >= i)
      return StepState.complete;
    else
      return StepState.indexed;
  }
    
  Widget _typeStep() => Container(
    child: Stepper(
      
      controlsBuilder: (BuildContext context, {VoidCallback onStepContinue, VoidCallback onStepCancel}) {
        return Padding(
          padding: EdgeInsets.all(8.0),
          child: RaisedButton(
            onPressed: () {
              setState(() {
                currentStep < spr.length - 1 ? currentStep += 1 : currentStep = 0;
              });
            },
            color: Colors.blue,
            textColor: Colors.white,
            child: Text('Next'),
          ),
        );
      },
      
      steps: _getSteps(),
      currentStep: currentStep,
      type: StepperType.horizontal,
      onStepTapped: (step) {
        setState(() {
          currentStep = step;
          print(step);
        });
      },
      onStepCancel: () {
        setState(() {
          currentStep > 0 ? currentStep -= 1 : currentStep = 0;
        });
      },
      onStepContinue: () {
        setState(() {
          currentStep < spr.length - 1 ? currentStep += 1 : currentStep = 0;
        });
      },
    ),
  ); 
}

Step One View

Next we create file StepOneView.dart which contain Form widget as content of Step 1.

import 'package:flutter/material.dart';

class StepOneView extends StatefulWidget {
  StepOneView({Key key}) : super(key: key);
  
  @override
  _StepOneViewState createState() => _StepOneViewState();
}

class _StepOneViewState extends State<StepOneView>{
  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.all(10.0),
        child: Card(
          child: Column(
          children: <Widget>[
            new TextFormField(
              decoration: const InputDecoration(labelText: 'Text 1'),
              keyboardType: TextInputType.number,
            ),
            new TextFormField(
              decoration: const InputDecoration(labelText: 'Text 2'),
              keyboardType: TextInputType.number,
            ),
            
          ],
        ),
        )
    );
  }

Step Two View

And the last we create file StepTwoView.dart which contain ListView widget as content of Step 2.

import 'package:flutter/material.dart';

class StepTwoView extends StatefulWidget {
  StepTwoView({Key key}) : super(key: key);
  
  @override
  _StepTwoViewState createState() => _StepTwoViewState();
}

class _StepTwoViewState extends State<StepTwoView>{

  Widget _myListView(BuildContext context) {
    // backing data
    final listData = ['Data 1', 'Data 2', 'Data 3', 'Data 4', 'Data 5', 'Data 6'];

    return ListView.separated(
      separatorBuilder: (context, index) => Divider(
        color: Colors.black,
      ),
      shrinkWrap: true,
      itemCount: listData.length,
      itemBuilder: (context, index) {
        return ListTile(
          title: Text(listData[index]),
        );
      },
      
    );

  }

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.all(10.0),
        child: Card(child: Column(
          children: <Widget>[
            _myListView(context)
          ]
        ),)
        
    );
  }
}

Main View

Now we call class StepperView.dart inside main.dart.

import 'package:flutter/material.dart';
import 'package:stepper_content_widget/StepperView.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Stepper Content Widget',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Stepper Content Widget'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: StepperView(),
    );
  }
}

Ok we’ve done now, then running our project, you can get result like this.

Step 1

stepper content form

Step 2

stepper content listview

What was you learned, from here:

  1. Stepper
  2. Form Text Box
  3. Listview

For full source code, you can get here, you can also see demo video here.

You can also learn more about Stepper by visit Here

Stay tuned for more tutorial, you can check this to see all of flutter tutorials.

HAPPY SHARE.

Advertisements
Share: