In onpressed(), print works. "addUpToFirst() executed in 0:00:00.047199" I expected duration value should be changed to 0:00:00.047199. in layout. but it isn't. still 0. I don't know why setState change duration value in layout. I need help. Thank you.
CodePudding user response:
You're not using any state
variable.
In a StatefulWidget
you usually have some class properties (or variables), whereas you're declaring everything inside your build
method. Here's the problem. You should move that variable outside the build
method and make it a class property.
You always had 0
in your layout because, even though you correctly invoke and use setState
to update duration
, every time setState
is called, by definition the build
method is re-run and therefore you re-initialize duration
to zero in the next rebuild.
This is why the print
statement worked (it's in the button callback and executes in its own scope) while the layout didn't.
Code (I didn't test it):
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var duration = Duration(microseconds: 0); // This is the only change!
@override
Widget build(BuildContext context) {
String str_addUpToFirst = '''
int addUpToFirst(n) {
var total = 0;
for (var i = 0; i <= n; i ) {
total = i;
}
return total;
}
''';
int addUpToFirst(n) {
var total = 0;
for (var i = 0; i <= n; i ) {
total = i;
}
return total;
}
return Scaffold(
body: Column(
children: [
Expanded(
child: Container(
width: double.infinity,
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Performance Tracker"),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
Stopwatch stopwatch = new Stopwatch()..start();
addUpToFirst(10000000);
duration = stopwatch.elapsed;
});
print('addUpToFirst() executed in ${duration}');
},
child: Text("addUpToFirst"),
),
ElevatedButton(
onPressed: () {},
child: Text("addUpToSecond"),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(),
width: 50,
child: TextField()),
ElevatedButton(
onPressed: () {},
child: Text('Plot!'),
),
],
)
],
),
),
flex: 1,
),
Expanded(
child: Container(
// color: Colors.black,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.grey,
child: Padding(
padding: EdgeInsets.only(top: 20),
child: Align(
alignment: Alignment.topCenter,
child: LayoutBuilder(
builder: (context, constraints) {
return Container(
color: Colors.yellow[100],
width: constraints.maxWidth * 0.9,
height: constraints.maxHeight * 0.5,
child: Text(str_addUpToFirst),
);
},
),
),
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Text('$duration'),
),
),
],
),
),
flex: 2,
),
],
),
);
}
}
CodePudding user response:
When you call the setState method, the build method is called again. So the value that needs to be changed remains the same.
So instead of declaring variables inside the build method, you need to call variables outside the build method.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Duration duration = const Duration(microseconds: 0);
String str_addUpToFirst = '''
int addUpToFirst(n) {
var total = 0;
for (var i = 0; i <= n; i ) {
total = i;
}
return total;
}
''';
int addUpToFirst(n) {
var total = 0;
for (var i = 0; i <= n; i ) {
total = i;
}
return total;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
child: Container(
width: double.infinity,
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text("Performance Tracker"),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
setState(() {
Stopwatch stopwatch = new Stopwatch()..start();
addUpToFirst(10000000);
duration = stopwatch.elapsed;
});
print('addUpToFirst() executed in ${duration}');
},
child: const Text("addUpToFirst"),
),
ElevatedButton(
onPressed: () {},
child: const Text("addUpToSecond"),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
decoration: const BoxDecoration(),
width: 50,
child: const TextField()),
ElevatedButton(
onPressed: () {},
child: const Text('Plot!'),
),
],
)
],
),
),
flex: 1,
),
Expanded(
child: Container(
// color: Colors.black,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: Align(
alignment: Alignment.topCenter,
child: LayoutBuilder(
builder: (context, constraints) {
return Container(
color: Colors.yellow[100],
width: constraints.maxWidth * 0.9,
height: constraints.maxHeight * 0.5,
child: Text(str_addUpToFirst),
);
},
),
),
),
),
),
Expanded(
child: Container(
color: Colors.white,
child: Text('$duration'),
),
),
],
),
),
flex: 2,
),
],
),
);
}
}