Is it possible to update a variable outside a widget while calling it ? Here's an example :
class Widget1 extends StatefulWidget {
@override
State<Widget1> createState() => _Widget1State();
}
class _Widget1State extends State<Widget1> {
String example = 'A';
@override
Widget build(BuildContext context) {
return Column(children: [
Text(example),
Widget2(example: example)
],);
}
}
class Widget2 extends StatefulWidget {
final String example;
Widget2({required this.example});
@override
State<Widget2> createState() => _Widget2State();
}
class _Widget2State extends State<Widget2> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => setState(() {
widget.example = 'B'
}),
child: Text('update !'),
);
}
}
The idea here is that I want to update example
using a button outside the widget.
This code is not working : example = 'A'
no matter if I click the button or not, but I don't understand why since I'm calling the same variable.
Is there a simple solution to achieve this ? (by simple, I mean without the need of Provider or else.)
CodePudding user response:
You can use callback method. Parent widget needed to updated, so setState is needed to be trigger on Widget1
.
class Widget1 extends StatefulWidget {
@override
State<Widget1> createState() => _Widget1State();
}
class _Widget1State extends State<Widget1> {
String example = 'A';
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(example),
Widget2(
example: example,
callback: (p0) {
setState(() {
example = p0;
});
},
),
],
);
}
}
class Widget2 extends StatefulWidget {
final String example;
final Function(String) callback;
Widget2({
required this.example,
required this.callback,
});
@override
State<Widget2> createState() => _Widget2State();
}
class _Widget2State extends State<Widget2> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
widget.callback("new data");
},
child: Text('update !'),
);
}
}
CodePudding user response:
You can use Notifiers, here is an example:
import 'package:flutter/material.dart';
class ExampleNotifier with ChangeNotifier {
String example = 'A';
ExampleNotifier();
setText(string x) {
example = x;
notifyListeners();
}
}
and then use it like:
class Widget1 extends StatefulWidget {
@override
State<Widget1> createState() => _Widget1State();
}
class _Widget1State extends State<Widget1> {
@override
Widget build(BuildContext context) {
var exampleNotifier = Provider.of<ExampleNotifier>(context);
return Column(
children: [
Text(exampleNotifier.example),
Widget2(),
],
);
}
}
class Widget2 extends StatefulWidget {
@override
State<Widget2> createState() => _Widget2State();
}
class _Widget2State extends State<Widget2> {
@override
Widget build(BuildContext context) {
var exampleNotifier = Provider.of<ExampleNotifier>(context, listen: false);
return ElevatedButton(
onPressed: () {
exampleNotifier.setText('B');
},
child: Text('update !'),
);
}
}