Flutter Dart setState not working: Unhandled Exception: setState() called in constructor: ...(lifecycle state: created, no widget, not mounted) - flutter

I am new to dart / flutter. I am changing the default app created by flutter create command. This is the code (I want to show information from EventSource):
import 'dart:async';
import 'package:w3c_event_source/event_source.dart';
import 'package:flutter/material.dart';
import 'blocs/main_bloc.dart';
void main() async {
runApp(MyApp());
final events = EventSource(Uri.parse("https://example.com/broadcast/"));
final subscription = events.events.listen((MessageEvent message) {
var myhomepagestate = MyHomePageState();
myhomepagestate.eventsource_message = '${message.data}';
//print('${message.data}');
});
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'EXAMPLE',
home: MyHomePage(title: 'EXAMPLE'),
);
}
}
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 _myeventsource = "";
void set eventsource_message(message) {
//if (!mounted) return;
setState(() {
_myeventsource = message;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'EventSource:',
),
Text(
'$_myeventsource',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
The error is at this command:
setState(() {
_myeventsource = message;
});
The error is: Unhandled Exception: setState() called in constructor: MyHomePageState#8034c(lifecycle state: created, no widget, not mounted)
I have searching for one day and can't find the solution. Can anybody give a hint what I should look into? Can I just name the element, then change the element directly like HTML DOM?
Thanks.

You are instantiating a MyHomePageState widget that you will never need to do. Instead, you have to instantiate the MyHomePage. It does not work in this context though because MyHomePage is still not mounted anywhere. You are just instantiating it and trying to set the value.
Remove this part from the main method:
final events = EventSource(Uri.parse("https://example.com/broadcast/"));
final subscription = events.events.listen((MessageEvent message) {
var myhomepagestate = MyHomePageState();
myhomepagestate.eventsource_message = '${message.data}';
//print('${message.data}');
});
Modify your MyHomePageState like this (Add initState and dispose methods. They are like constructors and destructors):
class MyHomePageState extends State<MyHomePage> {
String _myeventsource = "";
/**
void set eventsource_message(message) {
//if (!mounted) return;
setState(() {
_myeventsource = message;
});
}
**/
// Init state is called once when the widget is mounted. It's more like a constructor for your stateful widget which gets called by flutter itself when the widget is mounted.
// You don't need to call this method explicitly.
// Note that it won't be called again on hot reload. Refer to the documentation for more about it
#override
void initState() {
super.initState();
final events = EventSource(Uri.parse("https://example.com/broadcast/"));
events.events.listen((MessageEvent message) {
setState(() => _myeventsource = message.data);
}
}
// And this method is like a destructor.
// Called automatically by flutter when this widget is removed.
#override
void dispose() {
// Remember to remove the listeners here
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'EventSource:',
),
Text(
'$_myeventsource',
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}

Related

How to show SnackBar in ValueNotifier state manager

I'm working on a PageView with States managed by ValueNotifier. I choose ValuNotifier because it is fast and native. The ValueListenableBuilder works great for a regular page with states like loading, success and error where the body is rebuilt with the content state.
In the code above, ValueListenableBuilder rebuild the body page when state changes, but some states should only push SnackBar and should keep the current value.
What is the best way to handler error (or warning) in SnackBar or Dialog, keeping the body page with the current state (with data, for example)?
All states (even error) carry all data to rebuild the body, than I show SnackBar and rebuild the body;
Show SnackBar by one callback, viewpage will register one controller callback and do all the process to get the context and show SnackBar;
In my point of view, the 2nd distort the ideia of state manager but avoid to rebuild body; but the 1st looks over by the fact I have to carry all information all the time and 'rebuild' everything. I think, the 1st could be a big problem if body has animated transitions.
Do you recomend a 3rd alternative?
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
// ======= Controller =======
class CounterState {}
class SuccessCounterState extends CounterState {
final int currentValue;
SuccessCounterState(this.currentValue);
}
class MaxCounterState extends CounterState {}
class MinCounterState extends CounterState {}
class Counter extends ValueNotifier<CounterState> {
Counter() : super(SuccessCounterState(0));
var _localValue = 0;
void increment() {
if (_localValue + 1 > 9) {
value = MaxCounterState();
} else {
_localValue++;
value = SuccessCounterState(_localValue);
}
}
void decrement() {
if (_localValue - 1 < 0) {
value = MinCounterState();
} else {
_localValue--;
value = SuccessCounterState(_localValue);
}
}
}
// ==== Page ====
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final counter = Counter();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
ValueListenableBuilder<CounterState>(
valueListenable: counter,
builder: (BuildContext context, state, _) {
if (state is SuccessCounterState) {
return Text(
'${state.currentValue}',
style: Theme.of(context).textTheme.headline4,
);
}
if (state is MaxCounterState) {
Future.delayed(const Duration(milliseconds: 1), () {
const snackBar =
SnackBar(content: Text('Reached the max value'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}
if (state is MinCounterState) {
Future.delayed(const Duration(milliseconds: 1), () {
const snackBar =
SnackBar(content: Text('Reached the min value'));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}
return const SizedBox();
},
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: counter.decrement,
tooltip: 'Decrement',
child: const Icon(Icons.remove),
),
const SizedBox(width: 20.0),
FloatingActionButton(
onPressed: counter.increment,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
],
),
);
}
}

Please explain what #override, initState, super.initState means in simple terms

I browsed these words on internet but I couldn't find a simple explanation.
#override
void initState() {
super.initState();
_loadCounter();
}
I was going through a example code on flutter cookbook > Persistence >Store key-value data on disk https://flutter.dev/docs/cookbook/persistence/key-value
Complete code:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of the application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Shared preferences demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Shared preferences demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
#override
void initState() {
super.initState();
_loadCounter();
}
//Loading counter value on start
void _loadCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = (prefs.getInt('counter') ?? 0);
});
}
//Incrementing counter after click
void _incrementCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = (prefs.getInt('counter') ?? 0) + 1;
prefs.setInt('counter', _counter);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
#override
points out that the function is also defined in an ancestor class, but is being redefined to do something else in the current class. It is optional to use but recommended as it improves readability.
super.initState()
forwards to the default implementation of the State base class of your widget. If you don't override, the default implementation will not be executed but the widget depends on that to work properly.
initState
is called when the widget is inserted in widget tree... it means whenever the widget with is called it would run initState function at first.... it would be called only once and if you reState that widget it won't be called again

Flutter - Best way to aggregate data from child widgets in an IndexedStack

I have an IndexedStack in a Scaffold that I use to manage my registration. The Registration widget itself is Stateful, but the widgets that compose it are Stateless. The parent widget looks like this:
class Registration extends StatefulWidget {
#override
_RegistrationState createState() => _RegistrationState();
}
class _RegistrationState extends State<Registration> {
int _index = 0;
void _nextPage() {
setState(() {
_index++;
});
}
void _prevPage() {
setState(() {
_index--;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
leading: new IconButton(
icon: new Icon(Icons.arrow_back,
color: Theme.of(context).primaryColor),
onPressed: () {
if (_index == 0) {
Navigator.pop(context);
} else {
_prevPage();
}
}),
elevation: 0.0,
),
body: IndexedStack(
children: <Widget>[
RegistrationPhone(_nextPage),
RegistrationName(_nextPage),
RegistrationBirthday(_nextPage),],
index: _index,
),
);
}
}
What is the best way to take data from these child widgets?
Should I pass in a callback function and hold the data in the parent? Should I pass the information down the line from widget to widget until it's submitted? I don't know what the practices are for sharing data across multiple screens.
Use Provider
Add Dependency :
dependencies:
provider: ^4.3.3
here is the Example :
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
/// This is a reimplementation of the default Flutter application using provider + [ChangeNotifier].
void main() {
runApp(
/// Providers are above [MyApp] instead of inside it, so that tests
/// can use [MyApp] while mocking the providers
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: const MyApp(),
),
);
}
/// Mix-in [DiagnosticableTreeMixin] to have access to [debugFillProperties] for the devtool
// ignore: prefer_mixin
class Counter with ChangeNotifier, DiagnosticableTreeMixin {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
/// Makes `Counter` readable inside the devtools by listing all of its properties
#override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(IntProperty('count', count));
}
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Example'),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
Text('You have pushed the button this many times:'),
/// Extracted as a separate widget for performance optimization.
/// As a separate widget, it will rebuild independently from [MyHomePage].
///
/// This is totally optional (and rarely needed).
/// Similarly, we could also use [Consumer] or [Selector].
Count(),
],
),
),
floatingActionButton: FloatingActionButton(
key: const Key('increment_floatingActionButton'),
/// Calls `context.read` instead of `context.watch` so that it does not rebuild
/// when [Counter] changes.
onPressed: () => context.read<Counter>().increment(),
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class Count extends StatelessWidget {
const Count({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Text(
/// Calls `context.watch` to make [Count] rebuild when [Counter] changes.
'${context.watch<Counter>().count}',
key: const Key('counterState'),
style: Theme.of(context).textTheme.headline4);
}
}

Flutter - Update parant widget class UI on child button click

I have such kind of scenario
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
),
body: Container(
child: ChildWidget(
listControl: this.sentToScreenBuildJson,
notifyParent: refresh,
),
),
);
}
this is my parent build method where I have added ChildWidget a another statfulscreen and passing is a json and a refresh funtion
as per json child will able to draw UI
and on button click I am able to get callback to refresh method.
refresh() {
print("I get refreshed from child");
setState(() {
print("I get refreshed from child in setState");
this.sentToScreenBuildJson = this.newJson;
});
}
on button click both print get execute but UI is not updating as per newJson.
Like I am expecting that as setState run parent has to call build with passing updated json.
which is not working.
thanks for any help.
When you want to pass data from Child to Parent you should use NotificationListener at parent and dispatch Notification from child.
Instance of Notification class will be having data that you can consume in Parent using NotificationListener.
Mostly all the Flutter Widgets are using this technique, for example tab controller receive OverscrollNotification when user reaches to the last tab and still try to swipe.
Following is the demo that you can use to understand how you can use NotificationListener in your code.
import 'package:flutter/material.dart';
void main() => runApp(ParentWidget());
class ParentWidget extends StatefulWidget {
ParentWidget({Key key}) : super(key: key);
#override
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
String _text = 'You have not pressed the button yet';
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: NotificationListener<IntegerNotification>(
onNotification: (IntegerNotification notification) {
setState(() {
print(notification);
_text = 'You have pressed button ${notification.value} times';
});
return true;
},
child: Column(
children: <Widget>[
Text(_text),
ChildWidget(),
],
)
),
),
);
}
}
class ChildWidget extends StatefulWidget {
const ChildWidget({Key key}) : super(key: key);
#override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
int _counter = 0;
#override
Widget build(BuildContext context) {
return RaisedButton(onPressed: (){
IntegerNotification(++_counter).dispatch(context);
},child: Text('Increment counter'),);
}
}
#immutable
class IntegerNotification extends Notification{
final int value;
const IntegerNotification(this.value);
String toString(){
return value.toString();
}
}
Update parant widget class UI on child button click
This is a common use case in flutter and flutter has built in InheritedWidget class for these kind of purpose. You may either directly use it for your purpose or use some ready made package solution which uses InheritedWidget behind the scenes like Provider.
An alternative to #Darish's answer, you can declare a static variable in your class 1, access that static variable in class 2 and then update the state of the variable in the class 2.
For example:
import 'package:flutter/material.dart';
class Demo extends StatefulWidget {
static UserObject userObject;
#override
_Demo createState() => _Demo();
}
class _Demo extends State<Demo> {
#override
void initState() {
Demo.userObject = new UserObject(name: "EXAMPLE NAME");
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xfff3f3f3),
appBar: AppBar(title: Text("DEMO")),
body: InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => HeroClass()));
},
child: Center(
child: Hero(
tag: "tag-demo-id",
child: Container(
color: Colors.black,
padding: EdgeInsets.all(20),
child: Text("${Demo.userObject.name} -> CLICK HERE",
style: TextStyle(color: Colors.white)))))));
}
}
class HeroClass extends StatefulWidget {
#override
_HeroClassState createState() => _HeroClassState();
}
class _HeroClassState extends State<HeroClass> {
final myController = TextEditingController();
#override
void initState() {
myController.text = Demo.userObject.name;
super.initState();
}
#override
void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the _printLatestValue listener.
myController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("DEMO HERO")),
body: Hero(
tag: "tag-demo-id",
child: Container(
child: TextField(
controller: myController,
),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
Demo.userObject.name = myController.text;
});
},
child: Icon(Icons.save),
));
}
}
// object class
class UserObject {
String name;
UserObject({this.name});
UserObject.fromJson(Map<String, dynamic> json) {
name = json['name'];
}
}

Accessing a method of state class using its stateful widget?

I have a method in state class, but I need to access that method in outside using its widget class reference,
class TestFormState extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _testState();
}
}
class _testFormState extends State<TestFormState> {
int count = 1;
#override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.green,
child: Text("Count : $count"),
),
);
}
clickIncrease(){
setState(() { count += 1; });
}
}
and I need to access the above widget`s clickIncrease in another widget, like below code,
class TutorialHome extends StatelessWidget {
TestFormState test;
#override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
body: Column(
children: <Widget>[
test = TestFormState(),
FlatButton(
child: Text("Increase"),
onPressed: (){
test.state.clickIncrease(); // This kind of thing I need to do
},
),
]
),
);
}
I wrote above code just for demostrate the issue.
I have a trick, but I don't know if it is a bad practice or not.
class TestFormState extends StatefulWidget {
_TestFormState _testFormState;
#override
State<StatefulWidget> createState() {
_testFormState = _TestFormState();
return _testFormState;
}
}
class _TestFormState extends State<TestFormState> {
int count = 1;
#override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.green,
child: Text("Count : $count"),
),
);
}
clickIncrease(){
setState(() { count += 1; });
}
}
Now, you can access it here :
class TutorialHome extends StatelessWidget {
TestFormState test;
#override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
body: Column(
children: <Widget>[
TextButton(
child: Text("Increase"),
onPressed: () {
test._testFormState
.clickIncrease(); // This is accessable
},
),
]
),
);
}
}
I suggest taking a look at ValueNotifier
I think there is a better way to manage your app state in an easy way and I agree that using provider could be effective.
Provide the model to all widgets within the app. We're using
ChangeNotifierProvider because that's a simple way to rebuild
widgets when a model changes. We could also just use Provider, but
then we would have to listen to Counter ourselves.
Read Provider's docs to learn about all the available providers.
Initialize the model in the builder. That way, Provider can own
Counter's lifecycle, making sure to call dispose when not needed
anymore.
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
Simplest possible model, with just one field. ChangeNotifier is a
class in flutter:foundation. Counter does not depend on Provider.
class Counter with ChangeNotifier {
int count = 1;
void clickIncrease() {
count += 1;
notifyListeners();
}
}
Consumer looks for an ancestor Provider widget and retrieves its
model (Counter, in this case). Then it uses that model to build
widgets, and will trigger rebuilds if the model is updated.
You can access your providers anywhere you have access to the context.
One way is to use Provider<Counter>.of(context).
The provider package also defines extension methods on context itself.
You can call context.watch<Counter>() in a build method of any
widget to access the current state of Counter, and to ask Flutter to
rebuild your widget anytime Counter changes.
You can't use context.watch() outside build methods, because that
often leads to subtle bugs. Instead, you should use
context.read<Counter>(), which gets the current state but doesn't
ask Flutter for future rebuilds.
Since we're in a callback that will be called whenever the user taps
the FloatingActionButton, we are not in the build method here. We
should use context.read().
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count:'),
Consumer<Counter>(
builder: (context, counter, child) => Text(
'${counter.value}',
style: Theme.of(context).textTheme.headline4,
),
),
],
),
),
// I've change the button to `FloatingActionButton` for better ui experience.
floatingActionButton: FloatingActionButton(
// Here is the implementation that you are looking for.
onPressed: () {
var counter = context.read<Counter>();
counter.increment();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Complete code:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
class Counter with ChangeNotifier {
int count = 1;
void clickIncrease() {
count += 1;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count:'),
Consumer<Counter>(
builder: (context, counter, child) => Text(
'${counter.count}',
style: Theme.of(context).textTheme.headline4,
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
var counter = context.read<Counter>();
counter.clickIncrease();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Actual app:
For more information on the provider package (where Provider comes from), please see the package documentation.
For more information on state management in Flutter, and a list of other approaches, head over to the State management page at flutter.dev.
There is a built in method findAncestorStateOfType to find Ancestor _MyAppState class of the Parent MyApp class.
Here is the Code
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
static void setLocale(BuildContext context, Locale locale) {
_MyAppState? state = context.findAncestorStateOfType<_MyAppState>();
state!.setLocale(locale);
}
#override
_MyAppState createState() => _MyAppState();
}
// ignore: use_key_in_widget_constructors
class _MyAppState extends State<MyApp> {
// const MyApp({Key? key}) : super(key: key)
late Locale _locale;
void setLocale(Locale value) {
setState(() {
_locale = value;
});
}
}
class TestForm extends StatelessWidget {
final int _count;
TestForm(int count) : _count = count;
#override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.green,
child: Text('Count : $_count'),
),
);
}
}
class TutorialHome extends StatefulWidget {
#override
State<TutorialHome> createState() => _TutorialHomeState();
}
class _TutorialHomeState extends State<TutorialHome> {
int _count = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
TestForm(_count), // <---
TextButton(
child: Text("Increase"),
onPressed: () => setState(() => _count++),
),
],
),
);
}
}