I am building an onboarding feature with three pages:
PageView Widget
and loads Pages 1 and 2 with widgets.add()
methodonChanged
Page 0:
class Page0 extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _Page0State();
}
class _Page0State extends State<Page0> {
late UserPreferencesArguments? args;
int currentPage = 0;
static const _kDuration = const Duration(milliseconds: 500);
static const _kCurve = Curves.ease;
PageController pageController = PageController();
final globalScaffoldKey = GlobalKey<ScaffoldState>();
List<Widget> widgets = [];
@override
void initState() {
super.initState();
init();
}
init() async {
widgets.add(Page1());
widgets.add(Page2());
}
@override
void dispose() {
//pageController?.dispose();
super.dispose();
}
@override
void setState(fn) {
if (mounted) super.setState(fn);
}
@override
Widget build(BuildContext context) {
args = ModalRoute.of(context)?.settings.arguments as UserPreferencesArguments?;
return SafeArea(
child: Scaffold(
key: globalScaffoldKey,
body: Stack(
children: [
Container(
child: PageView(
scrollDirection: Axis.horizontal,
controller: pageController,
children: widgets,
onPageChanged: (i) {
currentPage = i;
setState(() {});
},
),
),
Positioned(
child: Container(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
shadowColor: Colors.grey,
),
onPressed: () {
if (currentPage == 1) {
updateAttributes(args?.aaa, args?.bbb);
Navigator.pushReplacementNamed(context, '/homepage');
} else {
pageController.nextPage(duration: _kDuration, curve: _kCurve);
}
},
child: Text(currentPage == 1 ? 'Finish' : "Next",),
),
),
),
],
)
),
);
}
updateAttributes(aaa, bbb) async {
debugPrint('devid: ${aaa}');
debugPrint('devid: ${bbb}');
}
}
Page 2:
class Page2 extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _Page2State();
}
class _Page2State extends State<Page2> {
String aaaImportValue = "";
String? _valAAA;
List _aaaList = ["1", "2" ];
String bbbImportValue = "";
String? _valBBB;
List _bbbList = ["3", "4" ];
@override
void initState() {
super.initState();
init();
}
init() async {}
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
child: DropdownButton<String>(
hint: Text("Select").tr(),
value: _valAAA,
items: _aaaList.map((value) {
return DropdownMenuItem<String>(
child: Text(value),
value: value,
);
}).toList(),
onChanged: (String? value) {
setState(() {
_valAAA = value!;
});
},
),
),
Container(
child: DropdownButton<String>(
hint: Text("Select").tr(),
value: _valBBB,
items: _bbbList.map((value) {
return DropdownMenuItem<String>(
child: Text(value),
value: value,
);
}).toList(),
onChanged: (String? value) {
setState(() {
_valBBB = value!;
});
},
),
),
],
);
}
}
I tried passing the dropdown values in this way but this just navigates to Page0:
onChanged: (String? value) {
setState(() {
_valBBB = value!;
if(_valBBB != null){
Navigator.pushNamed(context, "/Page0",
arguments: UserPreferencesArguments(_valAAA, _valBBB));
}
});
},
You can use callback method on Page2,
class Page2 extends StatefulWidget {
final Function(String? value1, String? value2) callback;
const Page2({
Key? key,
required this.callback,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _Page2State();
}
Now value changed , call
onChanged: (String? value) {
setState(() {
_valAAA = value!;
});
widget.callback(_valAAA, _valBBB);
},
And you will get value
init() async {
widgets.add(Page1());
widgets.add(Page2(
callback: (value1, value2) {
},
));
}
Tests snippet
class Page0 extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _Page0State();
}
class _Page0State extends State<Page0> {
int currentPage = 0;
PageController pageController = PageController();
final globalScaffoldKey = GlobalKey<ScaffoldState>();
List<Widget> widgets = [];
@override
void initState() {
super.initState();
init();
}
String? value1, value2;
init() async {
widgets.add(Text("Page1"));
widgets.add(Page2(
callback: (v1, v2) {
value1 = v1;
value2 = v2;
log("value 1 $value1 value2 $value2");
},
));
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: globalScaffoldKey,
body: Stack(
children: [
PageView(
scrollDirection: Axis.horizontal,
controller: pageController,
children: widgets,
onPageChanged: (i) {
currentPage = i;
setState(() {});
},
),
Center(child: Text("v1 $value1, v2 $value2"))
],
)),
);
}
}
class Page2 extends StatefulWidget {
final Function(String? value1, String? value2) callback;
const Page2({
Key? key,
required this.callback,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _Page2State();
}
class _Page2State extends State<Page2> {
String aaaImportValue = "";
String? _valAAA;
List _aaaList = ["1", "2"];
String bbbImportValue = "";
String? _valBBB;
List _bbbList = ["3", "4"];
@override
void initState() {
super.initState();
init();
}
init() async {}
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
child: DropdownButton<String>(
hint: Text("Select"),
value: _valAAA,
items: _aaaList.map((value) {
return DropdownMenuItem<String>(
child: Text(value),
value: value,
);
}).toList(),
onChanged: (String? value) {
setState(() {
_valAAA = value!;
});
widget.callback(_valAAA, _valBBB);
},
),
),
Container(
child: DropdownButton<String>(
hint: Text("Select"),
value: _valBBB,
items: _bbbList.map((value) {
return DropdownMenuItem<String>(
child: Text(value),
value: value,
);
}).toList(),
onChanged: (String? value) {
setState(() {
_valBBB = value!;
});
},
),
),
],
);
}
}