I'm trying to change the state of the screen through a StatefulBuilder ModalBottomSheet widget. But precisely by changing the background color of the main.dart screen. But the widget state change does not happen.
My question is: how do I call the update state of a StatefulBuilder ModalBottomSheet in another widget?
main.dart
import 'package:flutter/material.dart';
import 'package:modal.dart';
bool isEnable = false;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: isEnable ? Colors.amber : Colors.white,
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)),
),
backgroundColor: Colors.white,
context: context,
isScrollControlled: true,
builder: (context) {
return const ModalBottomSheet();
});
},
child: const Icon(Icons.change_circle_outlined),
),
);
}
}
modal.dart
import 'package:flutter/material.dart';
import 'package:main.dart';
class ModalBottomSheet extends StatefulWidget {
const ModalBottomSheet({super.key});
@override
_ModalBottomSheetState createState() => _ModalBottomSheetState();
}
class _ModalBottomSheetState extends State<ModalBottomSheet> {
bool light = true;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return StatefulBuilder(builder: (BuildContext context, StateSetter state) {
return Wrap(
children: <Widget>[
SafeArea(
child: Padding(
padding:
EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(isEnable.toString()),
Switch(
value: light,
activeColor: Colors.red,
onChanged: (bool value) {
state(() {
light = value;
isEnable = value;
});
},
)
],
),
),
)),
)
],
);
});
}
}
CodePudding user response:
how do I call the update state of a StatefulBuilder ModalBottomSheet in another widget?
To update the state of a widget from another widget somewhere else in the tree, you need some sort of scoped or global application state. I'd recommend taking a look at riverpod, but there are a multitude of other state management approaches out there.
CodePudding user response:
To update the values on a screen from a modal you can either use a state management solution or expose a function that returns the updated values to the parent widget. this works
import 'package:flutter/material.dart';
import 'package:modal.dart';
bool isEnable = false;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: isEnable ? Colors.amber : Colors.white,
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () {
showModalBottomSheet(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(15.0)),
),
backgroundColor: Colors.white,
context: context,
isScrollControlled: true,
builder: (context) {
return ModalBottomSheet(onSwitch: (bool value) {
setState(() {
isEnable = !isEnable;
});
});
});
},
child: const Icon(
Icons.change_circle_outlined,
),
),
);
}
}
modal.dart
class ModalBottomSheet extends StatefulWidget {
const ModalBottomSheet({super.key,required this.onSwitch});
final Function(bool value) onSwitch;
@override
_ModalBottomSheetState createState() => _ModalBottomSheetState();
}
class _ModalBottomSheetState extends State<ModalBottomSheet> {
bool light = true;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return StatefulBuilder(builder: (BuildContext context, StateSetter state) {
return Wrap(
children: <Widget>[
SafeArea(
child: Padding(
padding:
EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: SingleChildScrollView(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(isEnable.toString()),
Switch(
value: light,
activeColor: Colors.red,
onChanged: (bool value) {
setState(() {
light = !light;
});
widget.onSwitch!(value);
},
)
],
),
),
),
),
)
],
);
});
}
}