问题描述
我有一个单个表单,根据UX和UI设计要求,它分为3页。结构如下:
MyApp
|
|- BlocProvider.of<MyBloc>(context)
|- PageA
| |- FormA
| |- InputA
| |- InputB
| |- InputC
| |- RaisedButton (Next button)
|
|- PageB
| |- FormA
| |- InputD
| |- InputE
| |- InputF
| |- RaisedButton (Back button)
| |- RaisedButton (Next button)
|
|- PageC
| |- FormA
| |- InputG
| |- InputH
| |- InputI
| |- RaisedButton (Back button)
| |- RaisedButton (Submit button)
我想传递相同的状态,并更新onpressed
按钮的状态数据RaisedButton
,而不会将我的树包在blocbuilder,bloclistener
或{{1 }},因为不需要像在状态更改时重建小部件之类的事情。
我该怎么做?
注意
解决方法
我已经举了一个非常简单的例子,希望对您有所帮助。
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => MyForm(),child: MaterialApp(
title: 'Flutter Demo',home: HomePage(),),);
}
}
class HomePage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.stretch,children: [
BlocBuilder<MyForm,MyFromState>(
builder: (_,state) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,crossAxisAlignment: CrossAxisAlignment.center,children: [
Text('inputA: ${state.inputA}'),Text('inputB: ${state.inputB}'),Text('inputC: ${state.inputC}'),Text('inputD: ${state.inputD}'),Text('inputE: ${state.inputE}'),Text('inputF: ${state.inputF}'),],);
},Center(
child: RaisedButton(
onPressed: () {
Navigator.push(
context,MaterialPageRoute(builder: (context) => FirstPage()),);
},child: Text('start'),);
}
}
class FirstPage extends StatelessWidget {
Widget build(BuildContext context) {
var bloc = BlocProvider.of<MyForm>(context);
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
bloc.add(FirstPageSubmitEvent(
inputA: 'text1',inputB: 'text2',));
Navigator.push(
context,MaterialPageRoute(builder: (context) => SecondPage()),);
},child: Text('page 2'),);
}
}
class SecondPage extends StatelessWidget {
Widget build(BuildContext context) {
var bloc = BlocProvider.of<MyForm>(context);
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
bloc.add(SecondPageSubmitEvent(
inputC: 'text3',inputD: 'text4',MaterialPageRoute(builder: (context) => ThirdPage()),child: Text('page 3'),);
}
}
class ThirdPage extends StatelessWidget {
Widget build(BuildContext context) {
var bloc = BlocProvider.of<MyForm>(context);
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () {
bloc.add(ThirdPageSubmitEvent(
inputE: 'text5',inputF: 'text6',));
Navigator.pushAndRemoveUntil(
context,MaterialPageRoute(builder: (context) => HomePage()),(r) => r == null,);
}
}
class MyForm extends Bloc<MyFormEvent,MyFromState> {
MyForm() : super(MyFromState.empty);
@override
Stream<MyFromState> mapEventToState(MyFormEvent event) async* {
if (event is FirstPageSubmitEvent) {
yield (state.copyWith(
inputA: event.inputA,inputB: event.inputB,));
} else if (event is SecondPageSubmitEvent) {
yield (state.copyWith(
inputC: event.inputC,inputD: event.inputD,));
} else if (event is ThirdPageSubmitEvent) {
yield (state.copyWith(
inputE: event.inputE,inputF: event.inputF,));
}
}
}
abstract class MyFormEvent extends Equatable {}
class FirstPageSubmitEvent extends MyFormEvent {
FirstPageSubmitEvent({this.inputA,this.inputB});
final String inputA;
final String inputB;
@override
List<Object> get props => [inputA,inputB];
}
class SecondPageSubmitEvent extends MyFormEvent {
SecondPageSubmitEvent({this.inputC,this.inputD});
final String inputC;
final String inputD;
@override
List<Object> get props => [inputC,inputD];
}
class ThirdPageSubmitEvent extends MyFormEvent {
ThirdPageSubmitEvent({this.inputE,this.inputF});
final String inputE;
final String inputF;
@override
List<Object> get props => [inputE,inputF];
}
class MyFromState extends Equatable {
final String inputA;
final String inputB;
final String inputC;
final String inputD;
final String inputE;
final String inputF;
const MyFromState({
this.inputA,this.inputB,this.inputC,this.inputD,this.inputE,this.inputF,});
static const empty = MyFromState(
inputA: '',inputB: '',inputC: '',inputD: '',inputE: '',inputF: '',);
MyFromState copyWith({
String inputA,String inputB,String inputC,String inputD,String inputE,String inputF,}) {
return MyFromState(
inputA: inputA ?? this.inputA,inputB: inputB ?? this.inputB,inputC: inputC ?? this.inputC,inputD: inputD ?? this.inputD,inputE: inputE ?? this.inputE,inputF: inputF ?? this.inputF,);
}
@override
List<Object> get props => [inputA,inputB,inputC,inputD,inputE,inputF];
}