I have a root class RootPage
which is a StatefulWidget
which is always in view. I would like to change the body
in RootPage
Actually the most effective way to do this is using BLoC package in flutter and implement it from the top of the widget tree so all inheriting widgets can use the same bloc. If you have worked with Android before - it works like Android Architecture Components - you separate data and state management from the UI - so you do not setState in the UI, but instead use the BLoC to manage state. So you can set and access the same data - from any widget that inherits from the top widget where the BLoC is implemented, for more complex apps, it is very useful.
This is where you can find the package: https://pub.dev/packages/flutter_bloc#-readme-tab-
Write-up: https://www.didierboelens.com/2018/08/reactive-programming-streams-bloc/
And a great tutorial on youtube https://www.youtube.com/watch?v=hTExlt1nJZI&list=PLB6lc7nQ1n4jCBkrirvVGr5b8rC95VAQ5&index=7
This was a tricky question but I got a solution for this question I to faced this problem so many times. So let's first solve your problem. And this is the solution for your code
Lets first save this file with a name feedPage.dart
`import 'package:flutter/material.dart';
class FeedPage extends StatefulWidget {
@override
_feedPageState createState() => new _feedPageState();
}
class _feedPageState extends State<FeedPage> {
@override
Widget build(BuildContext context) {
return new FlatButton(
onPressed: () {
setState(() {
//change the currentPage in RootPage so it switches FeedPage away and gets a new class that I'll make
});
},
child: new Text('Go to a new page but keep root, just replace this feed part'),
);
}
}`
And then import that file into your main file
`
import 'package:flutter/material.dart';
import 'feedPage.dart'
class RootPage extends StatefulWidget {
@override
_RootPageState createState() => new _RootPageState();
}
class _RootPageState extends State<RootPage> {
FeedPage feedPage;
Widget currentPage;
@override
void initState() {
super.initState();
feedPage = FeedPage();
currentPage = feedPage;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
//Current page to be changed from other classes too?
body: currentPage
);
}
}`
In flutter you cant write multiple Stateful widgets in one dart file you have to create that as a widget and use it in your code as setState is an attribute of a Stateful widget we have write this code in an diffrent file
Problem Solved......:)
I know that you need a solution for your specific code but I recommed to you to have a look on BloC pattern as it the recommended aproch when you want to pass state changes from widget to another especially multiple pages
the idea is simple although the implementation is a "little bit" more complicated
You can use callbacks functions to achieve this. Please refer to the below code.
import 'package:flutter/material.dart';
class RootPage extends StatefulWidget {
@override
_RootPageState createState() => new _RootPageState();
}
class _RootPageState extends State<RootPage> {
FeedPage feedPage;
Widget currentPage;
@override
void initState() {
super.initState();
feedPage = FeedPage(this.callback);
currentPage = feedPage;
}
void callback(Widget nextPage) {
setState(() {
this.currentPage = nextPage;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
//Current page to be changed from other classes too?
body: currentPage
);
}
}
class FeedPage extends StatefulWidget {
Function callback;
FeedPage(this.callback);
@override
_feedPageState createState() => new _feedPageState();
}
class _feedPageState extends State<FeedPage> {
@override
Widget build(BuildContext context) {
return new FlatButton(
onPressed: () {
this.widget.callback(new NextPage());
// setState(() {
// //change the currentPage in RootPage so it switches FeedPage away and gets a new class that I'll make
// });
},
child: new Text('Go to a new page but keep root, just replace this feed part'),
);
}
}
This is very similar to this problem and you could refer 3rd point in my answer.