I am trying to understand how state works with Flutter, I have a child widget that needs to change something in the Parent widget. I can detect the push on the button in the child using a print. However when i try to bubble up this change to the parent its not catching it.
I have been though a number of tutorials and im not 100% sure I understand how state works or should work, I think I am missing something here.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
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> {
int _counter = 0;
//Consider this function as your _onNotification and important to note I am using setState() within :)
void _incrementCounter() {
print("pressed"); // Does not detect pressed.
setState(() {
_counter ; // counter is not increased
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.title,
style: TextStyle(color: Colors.white),
),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button $_counter times:',
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),
),
],
),
),
floatingActionButton: MyFloatButton(
_incrementCounter), //Pass delegate to _incrementCounter method
);
}
}
class MyFloatButton extends StatefulWidget {
// Here I am receiving the function in constructor as params
const MyFloatButton(this.onPressedFunction, {super.key});
// Should be the delegated function from _MyHomePageState
final Function onPressedFunction;
@override
_MyFloatButtonState createState() => new _MyFloatButtonState();
}
class _MyFloatButtonState extends State<MyFloatButton> {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: Colors.orangeAccent,
borderRadius: new BorderRadius.circular(50.0)),
child: IconButton(
icon: Icon(Icons.add),
color: Colors.white,
onPressed: () => {
//print('pressed') // Does work shows button pressed
widget.onPressedFunction
}, // call the delegated method to detect the pressed
),
);
}
}
Things tried:
onPressed: widget.onPressedFunction()
Results in
setState() or markNeedsBuild called during build
onPressed: widget.onPressedFunction
Results in
The argument type 'Function' can't be assigned to the parameter type 'void Function()?'.
onPressed: () => widget.onPressedFunction,
Results in
No change does not do anything
CodePudding user response:
Please try this. onPressedFunction is a function so declare like below function.
onPressed: () => {
widget.onPressedFunction()
},
CodePudding user response:
Inside the MyFloatButton you're calling a function inside a function
onPressed: () => {
//print('pressed') // Does work shows button pressed
widget.onPressedFunction
},
It should be as follows
onPressed: widget.onPressedFunction
CodePudding user response:
Change this
onPressed: () => {
//print('pressed') // Does work shows button pressed
widget.onPressedFunction
},
To this
onPressed: () => widget.onPressedFunction,
Just remove curly braces and add () here
floatingActionButton: MyFloatButton(
_incrementCounter())