Flutter : setState outside - flutter

I'm new to Flutter and I just want to understand something about stateful widget. Here's a simple code that works perfectly just by switching the text color from red to blue when clicking on a button :
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
MyWidget({Key? key}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Color myColor = Colors.red;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My app")),
body: Column(
children: [
Text(
"Just a simple text",
style: TextStyle(color: myColor),
),
FloatingActionButton(
onPressed: () {
setState(() {
myColor =
(myColor == Colors.red) ? Colors.blue : Colors.red;
});
print(myColor);
},
child: Icon(Icons.home)),
],
));
}
}
My question is : if I get the column outside the stateful widget and call it as a component, how and where should I rewrite the setState function ? I begin with this code and I don't know how to continue :
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
MyWidget({Key? key}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Color myColor = Colors.red;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My app")),
body: HomePage());
}
}
Column HomePage()
{
return Column(
children: [
Text(
"Just a simple text",
style: TextStyle(color: myColor), // SHOULD I NOW INJECT myColor AS A PARAMETER OF HomePage ?
),
FloatingActionButton(
onPressed: () {print("WHERE TO PUT THE setState FUNCTION NOW ???")},
child: Icon(Icons.home)),
],
);
}

Your HomePage() is just a function that returns a Column, so you can just include it within the _MyWidgetState class to be able to access the state directly, and call the setState method, like that:
import 'package:flutter/material.dart';
class MyWidget extends StatefulWidget {
MyWidget({Key? key}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Color myColor = Colors.red;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My app")),
body: HomePage());
}
Column HomePage(){
return Column(
children: [
Text(
"Just a simple text",
style: TextStyle(color: myColor), // SHOULD I NOW INJECT myColor AS A PARAMETER OF HomePage ?
),
FloatingActionButton(
onPressed: () {
setState(() {
myColor = Colors.amber;
});
},
child: Icon(Icons.home)),
],
);
}
}

Here's a example class for how to pass data from one class to another class
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'main1.dart';
void main() {
runApp(MaterialApp(
home: Modalbtn(),
));
}
class Modalbtn extends StatefulWidget {
#override
_ModalbtnState createState() => _ModalbtnState();
}
class _ModalbtnState extends State<Modalbtn> {
String value = "0";
// Pass this method to the child page.
void _update(String newValue) {
setState(() => value = newValue);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
IconButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
child: Column(
children: [StatefulModalbtn(update: _update)],
),
);
});
},
icon: Icon(Icons.add),
iconSize: 20,
),
Text(
value,
style: TextStyle(fontSize: 40),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
class StatefulModalbtn extends StatelessWidget {
final ValueChanged<String> update;
StatefulModalbtn({required this.update});
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => update("100"), // Passing value to the parent widget.
child: Text('Update (in child)'),
);
}
}

If you insist of having the HomePage() function outside the class you could do this for example:
class MyWidget extends StatefulWidget {
MyWidget({Key? key}) : super(key: key);
#override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
Color myColor = Colors.red;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My app")),
body: HomePage(myColor, changeColor));
}
void changeColor(Color color) {
setState((){
myColor = color;
});
}
}
Column HomePage(Color color, ValueSetter<Color> change)
{
return Column(
children: [
Text(
"Just a simple text",
style: TextStyle(color: color),
),
FloatingActionButton(
onPressed: () { change(Colors.blue);},
child: Icon(Icons.home)),
],
);
}

Related

set state Badge appbar - flutter

I'm trying to increment the app bar icon by making a custom app bar. But I can't update the value with setState. I tried to update the value by the setAppBarValue function, but it didn't work.
MyAppBar.of(context)?.setAppBarValue(_counter);
import 'package:badges/badges.dart';
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(
debugShowCheckedModeBanner: false,
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> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppBar(),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter();
MyAppBar.of(context)?.setAppBarValue(_counter);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class MyAppBar extends StatefulWidget implements PreferredSizeWidget {
MyAppBar() : super();
#override
Size get preferredSize => const Size.fromHeight(60);
#override
_MyAppBarState createState() => _MyAppBarState();
static _MyAppBarState? of(BuildContext context) =>
context.findAncestorStateOfType<_MyAppBarState>();
}
class _MyAppBarState extends State<MyAppBar>
with SingleTickerProviderStateMixin {
int _appBarValue = 0;
setAppBarValue(int value) {
setState(() {
_appBarValue = value;
});
}
#override
Widget build(BuildContext context) {
return AppBar(
title: const Text("teste"),
actions: <Widget>[Center(child: _alertBadge(context))]);
}
Widget _alertBadge(BuildContext context) {
return Badge(
position: BadgePosition.topEnd(
top: 0,
end: 3,
),
badgeStyle: BadgeStyle(
badgeColor: Colors.red,
),
badgeContent: Text(
_appBarValue.toString(),
style: TextStyle(color: Colors.white),
),
child:
IconButton(icon: Icon(Icons.shopping_bag_outlined), onPressed: () {}),
);
}
}
You Have to pass the increment variable value to the appbar widget like this:
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;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: MyAppBar(
appBarValue: _counter,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_incrementCounter();
// MyAppBar.of(context)?.setAppBarValue(_counter);
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
And use that value in your app bar widget:
class MyAppBar extends StatefulWidget implements PreferredSizeWidget {
const MyAppBar({
Key? key,
required this.appBarValue,
}) : super(key: key);
final int appBarValue;
#override
Size get preferredSize => const Size.fromHeight(60);
#override
_MyAppBarState createState() => _MyAppBarState();
static _MyAppBarState? of(BuildContext context) =>
context.findAncestorStateOfType<_MyAppBarState>();
}
class _MyAppBarState extends State<MyAppBar>
with SingleTickerProviderStateMixin {
// int _appBarValue = 0;
//
// setAppBarValue(int value) {
// setState(() {
// _appBarValue = value;
// });
// }
#override
Widget build(BuildContext context) {
return AppBar(
title: const Text("teste"),
actions: <Widget>[Center(child: _alertBadge(context))]);
}
Widget _alertBadge(BuildContext context) {
return Badge(
position: BadgePosition.topEnd(
top: 0,
end: 3,
),
badgeStyle: BadgeStyle(
badgeColor: Colors.red,
),
badgeContent: Text(
widget.appBarValue.toString(),
style: TextStyle(color: Colors.white),
),
child:
IconButton(icon: Icon(Icons.shopping_bag_outlined), onPressed: () {}),
);
}
}

Flutter - How to call this function?

I have something like that, I tried so many ways and can't call the function like I want.
class PageTest extends StatefulWidget {
PageTest({Key? key}) : super(key: key);
#override
State<PageTest> createState() => PageTestState();
}
class PageTestState extends State<PageTest> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: topMyBar(),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [PageTestList()],
),
),
floatingActionButton: floatingButton(),
);
}
Widget floatingButton() {
return FloatingActionButton.extended(
onPressed: () {
CALL pageTestListFunction() AND SETSTATE ON _PageTestListState;
},
backgroundColor: AppColors.status_ready,
label: Text(
'OK',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
));
}
}
-- END HERE --
class PageTestList extends StatefulWidget {
const PageTestList({Key? key}) : super(key: key);
#override
State<PageTestList> createState() => _PageTestListState();
}
class _PageTestListState extends State<PageTestList> {...
Future<bool> pageTestListFunction() async {...}
}
Is there a way to call the function from PageTestList when onPressed on floatingActionButton is called and then setState on PageTestList?
Thank's!
Use a global key in your widget.
class PageTest extends StatefulWidget {
const PageTest({Key? key}) : super(key: key);
#override
State<PageTest> createState() => PageTestState();
}
class PageTestState extends State<PageTest> {
final _globalkey = GlobalKey<PageTestListState>();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: topMyBar(),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [PageTestList(key:_globalkey)],
),
),
floatingActionButton: floatingButton(),
);
}
Widget floatingButton() {
return FloatingActionButton.extended(
onPressed: () {
//CALL pageTestListFunction() AND SETSTATE ON _PageTestListState;
_globalkey.currentState?.pageTestListFunction();
},
backgroundColor: AppColors.status_ready,
label: const Text(
'OK',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
));
}
}
class PageTestList extends StatefulWidget {
const PageTestList({Key? key}) : super(key: key);
#override
State<PageTestList> createState() => PageTestListState();
}
class PageTestListState extends State<PageTestList> {
var color = Colors.red;
void pageTestListFunction() async {
setState(() {
color = Colors.green;
});
}
#override
Widget build(BuildContext context) {
return Container(
color: color,
width: 100,
height: 100,
);
}
}

Changing the state Widget of one through another Widget

MyHomePageState:
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: bgColor,
body: ListView(
children: <Widget>[
Stack(
alignment: Alignment.topCenter,
children: <Widget>[
mainWidget(),
],
),
connectedStatusText(),
],
));
}
I'm trying to change the status of connectedStatusText() from mainWidget()!
My connectedStatus:
class connectedStatusText extends StatefulWidget
{
State<connectedStatusText> createState() {
return connectedStatus();
}
}
class connectedStatus extends State<connectedStatusText> {
String status = "IDLE";
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(text: 'Status:', style: connectedStyle, children: [
TextSpan(text: status, style: disconnectedRed)
]),
),
);
}
}
I want to change the $status text to "connected" through ontap of mainWidget().
mainWidget:
....
class mainWidget extends StatefulWidget
{
MyED createState() => new MyED();
}
class MyED extends State<mainWidget> {
child: new GestureDetector(
onTap: () => setState(() {
//change here
}
tried to set a global variable to connectedStatus:
GlobalKey<connectedStatus> key = GlobalKey<connectedStatus>();
and change by ontap...
child: new GestureDetector(
onTap: () => setState(() {
//change here
key.currentState.status = "CONNECTED";
}
)
}
but it does not work!
Any help for me to change this text through another place?
Please refer to below example code to update state using ValueNotifier and ValueListenableBuilder.
ValueNotifer & ValueListenableBuilder can be used to hold value and update widget by notifying its listeners and reducing number of times widget tree getting rebuilt.
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Screen2(),
);
}
}
class Screen2 extends StatefulWidget {
final String userId; // receives the value
const Screen2({Key key, this.userId}) : super(key: key);
#override
_Screen2State createState() => _Screen2State();
}
class _Screen2State extends State<Screen2> {
final ValueNotifier<bool> updateStatus = ValueNotifier(false);
#override
Widget build(BuildContext context) {
double screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
backgroundColor: Colors.blue,
body: ListView(
children: <Widget>[
Stack(
alignment: Alignment.topCenter,
children: <Widget>[
mainWidget(
updateStatus: updateStatus,
),
],
),
connectedStatusText(
updateStatus: updateStatus,
),
],
),
); // uses the value
}
}
class connectedStatusText extends StatefulWidget {
final ValueNotifier<bool> updateStatus;
connectedStatusText({
Key key,
this.updateStatus,
}) : super(key: key);
State<connectedStatusText> createState() {
return connectedStatus();
}
}
class connectedStatus extends State<connectedStatusText> {
String status = "IDLE";
#override
Widget build(BuildContext context) {
return Align(
alignment: Alignment.center,
child: /*
In order update widget we can use ValueListenableBuilder which updates the particular widget when the value changes (ValueNotifier value)
*/
ValueListenableBuilder(
valueListenable: widget.updateStatus,
builder: (context, snapshot, child) {
return RichText(
textAlign: TextAlign.center,
text: TextSpan(text: 'Status:', children: [
TextSpan(
text: (widget.updateStatus.value == true)
? "Active"
: status,
)
]),
);
}),
);
}
}
class mainWidget extends StatefulWidget {
final String userId; // receives the value
final ValueNotifier<bool> updateStatus;
mainWidget({
Key key,
this.userId,
this.updateStatus,
}) : super(key: key);
#override
_mainWidgetState createState() => _mainWidgetState();
}
class _mainWidgetState extends State<mainWidget> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
widget.updateStatus.value = !widget.updateStatus.value;
},
child: ValueListenableBuilder(
valueListenable: widget.updateStatus,
builder: (context, snapshot, child) {
return Text(snapshot.toString());
}));
// uses the value
}
}

How to invoke a rebuild of a stateless widget?

Context
I have two stateless widgets (pages): HomePage and DetailsPage. Obviously the application starts and launches the HomePage. There is a button the user can press to navigate to the DetailsPage with a Navigator.pop() button to navigate back to the HomePage.
I know when the DetailsPage is done being used with the .whenComplete() method. It is at this point I want to rebuild the HomePage widget.
Code
This is the minimum reproduction of my behavior.
main.dart
import 'package:example/home.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: HomePage());
}
}
home.dart
import 'package:example/details.dart';
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
static const name = 'Home Page';
const HomePage() : super();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: Text(name),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: DetailsPage.builder),
).whenComplete(() => print('Rebuild now.'));
},
),
),
);
}
}
details.dart
import 'package:flutter/material.dart';
class DetailsPage extends StatelessWidget {
static const name = 'Details Page';
static WidgetBuilder builder = (BuildContext _) => DetailsPage();
const DetailsPage();
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(name),
MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: Text('Go Back'),
onPressed: () => Navigator.pop(context),
),
],
),
),
);
}
}
Question
How can I invoke a rebuild of this stateless widget (HomePage) at the .whenComplete() method callback?
You can force rebuild the widget tree as follows:
class RebuildController {
final GlobalKey rebuildKey = GlobalKey();
void rebuild() {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(rebuildKey.currentContext as Element).visitChildren(rebuild);
}
}
class RebuildWrapper extends StatelessWidget {
final RebuildController controller;
final Widget child;
const RebuildWrapper({Key? key, required this.controller, required this.child}) : super(key: key);
#override
Widget build(BuildContext context) => Container(
key: controller.rebuildKey,
child: child,
);
}
In your case,
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final RebuildController controller = RebuildController();
MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: RebuildWrapper(
controller: controller,
child: HomePage(
rebuildController: controller,
),
),
);
}
}
class HomePage extends StatelessWidget {
static const name = 'Home Page';
final RebuildController rebuildController;
const HomePage({Key? key, required this.rebuildController}) : super(key: key);
#override
Widget build(BuildContext context) {
print('Hello there!');
return Scaffold(
body: Center(
child: MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: const Text(name),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: DetailsPage.builder),
).whenComplete(rebuildController.rebuild);
},
),
),
);
}
}
class DetailsPage extends StatelessWidget {
static const name = 'Details Page';
static WidgetBuilder builder = (BuildContext _) => const DetailsPage();
const DetailsPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(name),
MaterialButton(
color: Colors.blue,
textColor: Colors.white,
child: const Text('Go Back'),
onPressed: () => Navigator.pop(context),
),
],
),
),
);
}
}
class RebuildController {
final GlobalKey rebuildKey = GlobalKey();
void rebuild() {
void rebuild(Element el) {
el.markNeedsBuild();
el.visitChildren(rebuild);
}
(rebuildKey.currentContext as Element).visitChildren(rebuild);
}
}
class RebuildWrapper extends StatelessWidget {
final RebuildController controller;
final Widget child;
const RebuildWrapper({Key? key, required this.controller, required this.child}) : super(key: key);
#override
Widget build(BuildContext context) => Container(
key: controller.rebuildKey,
child: child,
);
}
But it is unnatural to force rebuild stateless widgets as they are not supposed to be rebuilt. You should use stateful widget or other state management solutions so that your HomePage will only be updated on meaningful state change.
Source - this answer

Flutter: Widget State: Is this code safe?

The code below is an example to illustrate this question. The code below works, however the following line:
class WidgetCustom extends StatefulWidget {
has "WidgetCustom" underlined in green in vsCode, and when the cursor is positioned over it, it shows the message:
"This class (or a class this class inherits from) is marked as #immutable, but one or more of its instance fields are not final".
The code works fine.
Is it safe to use this code?
Is there a way to achieve this without the warning?
import 'package:flutter/material.dart';
class WidgetCustom extends StatefulWidget {
_WidgetCustomState _state;
WidgetCustom({#required int iCount}) {
_state = _WidgetCustomState(iCount);
}
#override
State<StatefulWidget> createState() {
return _state;
}
int get getIcount => _state.iCount;
}
class _WidgetCustomState extends State<WidgetCustom> {
int iCount;
_WidgetCustomState(this.iCount);
#override
Widget build(BuildContext context) {
return Container(
child: Row(children: <Widget>[
Column(
children: <Widget>[
RaisedButton(
child: const Text("Please tap me"),
onPressed: () {
setState(() => iCount = iCount + 1);
}),
SizedBox(height: 40),
Text("Tapped $iCount Times")
],
),
]));
}
}
Edited to add main.dart
import 'package:flutter/material.dart';
import 'widgetCustom.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Custom Widget Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
WidgetCustom _widgetCustom;
String _sMessage = "Fab has not been pressed";
#override
void initState() {
super.initState();
_widgetCustom = WidgetCustom(iCount: 99);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(children: [
_widgetCustom,
SizedBox(height: 40),
Text(_sMessage),
]),
floatingActionButton: FloatingActionButton(
onPressed: _fabPressed,
tooltip: 'Get Value',
child: Icon(Icons.add),
),
);
}
_fabPressed() {
setState(() => _sMessage =
"Value from last button click = ${_widgetCustom.getIcount}");
}
}
Pass the initial value to the constructor when creating the widget as a final value, and then get it from the State class.
Updated code:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData.dark(),
home: MyHomePage(title: 'Custom Widget Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
WidgetCustom _widgetCustom;
String _sMessage = "Fab has not been pressed";
int _value = 99;
#override
void initState() {
super.initState();
_widgetCustom = WidgetCustom(iCount: _value, function: _update);
}
void _update(int value) {
setState(() {
_value = value;
_widgetCustom = WidgetCustom(iCount: _value, function: _update);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: Column(
children: [
_widgetCustom,
SizedBox(height: 40),
Text(_sMessage),
],
),
floatingActionButton: FloatingActionButton(
onPressed: _fabPressed,
tooltip: 'Get Value',
child: Icon(Icons.add),
),
);
}
_fabPressed() {
setState(() => _sMessage = "Value from last button click = ${_value}");
}
}
class WidgetCustom extends StatefulWidget {
final int iCount;
final Function function;
WidgetCustom({#required this.iCount, this.function});
#override
State<StatefulWidget> createState() {
return _WidgetCustomState();
}
}
class _WidgetCustomState extends State<WidgetCustom> {
int _iCount;
#override
void initState() {
super.initState();
_iCount = widget.iCount;
}
#override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Column(
children: <Widget>[
RaisedButton(child: const Text("Please tap me"), onPressed: (){
_iCount = _iCount + 1;
widget.function(_iCount);
}),
SizedBox(height: 40),
Text("Tapped $_iCount Times")
],
),
],
),
);
}
}