Created
June 26, 2019 02:52
-
-
Save felangel/ada82ee2bfc9178b1a772a3ec4fa77bc to your computer and use it in GitHub Desktop.
Flutter Bloc Stepper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:async'; | |
| import 'package:flutter/material.dart'; | |
| import 'package:bloc/bloc.dart'; | |
| import 'package:flutter_bloc/flutter_bloc.dart'; | |
| import 'package:equatable/equatable.dart'; | |
| abstract class StepperEvent extends Equatable { | |
| StepperEvent([List props = const []]) : super(props); | |
| } | |
| class StepTapped extends StepperEvent { | |
| final int step; | |
| StepTapped({@required this.step}) : super([step]); | |
| @override | |
| String toString() => 'StepTapped { step: $step }'; | |
| } | |
| class StepCancelled extends StepperEvent { | |
| @override | |
| String toString() => 'StepCancelled'; | |
| } | |
| class StepContinue extends StepperEvent { | |
| @override | |
| String toString() => 'StepContinue'; | |
| } | |
| class StepperState extends Equatable { | |
| final int step; | |
| final int maxSteps; | |
| StepperState({ | |
| @required this.step, | |
| @required this.maxSteps, | |
| }) : super([step, maxSteps]); | |
| StepperState copyWith({int step, int maxSteps}) { | |
| return StepperState( | |
| step: step ?? this.step, | |
| maxSteps: maxSteps ?? this.maxSteps, | |
| ); | |
| } | |
| @override | |
| String toString() => 'StepperState { step: $step, maxSteps: $maxSteps }'; | |
| } | |
| class StepperBloc extends Bloc<StepperEvent, StepperState> { | |
| final int maxSteps; | |
| StepperBloc({@required this.maxSteps}); | |
| @override | |
| StepperState get initialState => StepperState(step: 0, maxSteps: maxSteps); | |
| @override | |
| void onTransition(Transition<StepperEvent, StepperState> transition) { | |
| super.onTransition(transition); | |
| print(transition); | |
| } | |
| @override | |
| Stream<StepperState> mapEventToState(StepperEvent event) async* { | |
| if (event is StepTapped) { | |
| yield currentState.copyWith(step: event.step); | |
| } else if (event is StepCancelled) { | |
| yield currentState.copyWith( | |
| step: currentState.step - 1 >= 0 ? currentState.step - 1 : 0, | |
| ); | |
| } else if (event is StepContinue) { | |
| yield currentState.copyWith( | |
| step: currentState.step + 1 < maxSteps ? currentState.step + 1 : 0, | |
| ); | |
| } | |
| } | |
| } | |
| void main() { | |
| final List<Step> steps = [ | |
| Step( | |
| title: Text("Step 1"), | |
| content: Text("Hello!"), | |
| isActive: true, | |
| ), | |
| Step( | |
| title: Text("Step 2"), | |
| content: Text("World!"), | |
| state: StepState.editing, | |
| isActive: true, | |
| ), | |
| Step( | |
| title: Text("Step 3"), | |
| content: Text("Hello World!"), | |
| isActive: true, | |
| ), | |
| ]; | |
| runApp( | |
| MaterialApp( | |
| home: BlocProvider( | |
| builder: (context) => StepperBloc(maxSteps: steps.length), | |
| child: MyHome(steps: steps), | |
| ), | |
| ), | |
| ); | |
| } | |
| class MyHome extends StatelessWidget { | |
| final List<Step> steps; | |
| MyHome({Key key, @required this.steps}) : super(key: key); | |
| @override | |
| Widget build(BuildContext context) { | |
| print('MyHome build'); | |
| final stepperBloc = BlocProvider.of<StepperBloc>(context); | |
| return Scaffold( | |
| appBar: AppBar( | |
| title: Text('Flutter Bloc Stepper'), | |
| ), | |
| body: Container( | |
| child: BlocBuilder( | |
| bloc: stepperBloc, | |
| builder: (BuildContext context, StepperState state) { | |
| return Stepper( | |
| currentStep: state.step, | |
| steps: steps, | |
| type: StepperType.vertical, | |
| onStepTapped: (step) { | |
| stepperBloc.dispatch(StepTapped(step: step)); | |
| }, | |
| onStepCancel: () { | |
| stepperBloc.dispatch(StepCancelled()); | |
| }, | |
| onStepContinue: () { | |
| stepperBloc.dispatch(StepContinue()); | |
| }, | |
| ); | |
| }, | |
| ), | |
| ), | |
| ); | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for clarifying! Yeah I definitely recommend separating things where it makes sense because, like you said, it helps with reuse and modularity.
That's awesome! Thanks so much for the positive feedback and don't hesitate to ask any more questions regarding the bloc library either by opening an issue or posting a question in the chat 😄