I have a Stateful class, and the return of build is a PageView, and each one of pages have a Scafold and a body.
What I need is, my first page have in Scafold a action Button, to refresh the entire page (or rebuild my entire class, if I can).
I try create a setState in onTap from button, and create a StreamController, but, none of them resolve my problem.
import 'package:flutter/material.dart';
import 'package:plataforma_base/animations/loader.dart';
import 'package:plataforma_base/pages/home_body.dart';
import '../constantes/constantes.dart';
import 'dart:async';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final _pageController = PageController(
initialPage: 0,
);
final StreamController _stream = StreamController.broadcast();
@override
void dispose() {
_stream.close();
super.dispose();
}
void _refreshPage(){
_stream.sink.add(null);
}
@override
Widget build(BuildContext context) {
return
PageView(
controller: _pageController,
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
Scaffold(
appBar: new AppBar(
title: new Text(
"HOME",
),
backgroundColor: Color(Cores.corPrincipal),
centerTitle: true,
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh,color: Colors.white,),
onPressed: (){
_refreshPage();
}
),
],
),
drawer: CustomDrawer(_pageController),
body: StreamBuilder(
initialData: HomeBody(),
stream: _stream.stream,
builder: (context, snapshot){
Dialog(
child: Loader(),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
insetAnimationCurve: Cubic(2, 5, 10, 3),
insetAnimationDuration: Duration(seconds: 30),
);
return HomeBody();
},
),
),
],
);
}
}
If i miss some important information, please tell my to paste here.
This seems to be an interesting use case. The sample code you've provided is incomplete and I'm unable to run it locally. However, I did try a similar setup in this sample app. If a Stateful widget is used as a page in a PageView
, calling it's setState()
should refresh the individual pages.
Here's a sample that you can check. The FloatingActionButton
triggering the refresh action is in the Home page, while the refresh()
function it invokes is in Page 1.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var page1 = Page1();
@override
Widget build(BuildContext context) {
debugPrint('HomePage build');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: PageView(
children: [
page1,
_page2(),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
backgroundColor: Colors.blueAccent,
onPressed: () {
debugPrint('Refresh Page 1');
page1.getState().refresh();
},
),
);
}
_page2() {
return Container(
color: Colors.greenAccent,
);
}
}
class Page1 extends StatefulWidget {
Page1State page1State;
@override
Page1State createState() {
page1State = Page1State();
return page1State;
}
getState() => page1State;
}
class Page1State extends State<Page1> {
var refreshCount = 0;
refresh() {
debugPrint('Page 1 refresh');
setState(() {
refreshCount++;
});
}
@override
Widget build(BuildContext context) {
debugPrint('Page 1 build');
return Container(
color: Colors.lightBlueAccent,
child: Center(
child: Text('Refresh clicked $refreshCount times'),
),
);
}
}
Demo