Reputation: 22437
I managed to pass Stateful class variables' values to the State class through constructor like below:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: MyHomePage('John', 'Morison'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage(this.fname, this.lname);
final String fname;
final String lname;
@override
_MyHomePageState createState() => _MyHomePageState(fname, lname);
}
class _MyHomePageState extends State<MyHomePage> {
_MyHomePageState(this.fname, this.lname);
final String fname;
final String lname;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Hello $fname $lname'),
)
);
}
}
That's weird and I had to do lot of work as there is more than two variables. Is there a better way?
Upvotes: 7
Views: 6669
Reputation: 177
There is also a solution with not using the constructor provided in the Flutter Cookbook: https://docs.flutter.dev/cookbook/navigation/passing-data
The idea is using RouteSettings und ModalRoute; here the important code parts:
class _TodosScreenState extends State<TodosScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
// ...
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// Pass the arguments as part of the RouteSettings. The DetailScreen reads the arguments from these settings.
settings: RouteSettings(
// widget. is important to access the variable of the stateful class TodosScreen
arguments: widget.todos[index],
// ...
class _DetailScreenState extends State<DetailScreen> {
@override
Widget build(BuildContext context) {
// must be inside build method, as here is the context parameter available
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// accessing the variable as u wish
Text(todo.title)
Upvotes: 0
Reputation: 594
You can access your variables by widget.
like widget.myVariable
in the state class. however, it's the best practice to pass the variables to the state class constructor if you want to change them in the state class. remember that the variable must be defined as final in the parent (stateful) class, so if you want to change these variables you must define non-final variables in the state class and initiate their values by the constructor.
class RecordPage extends StatefulWidget {
final int myvVariable;
RecordPage({required this.myvVariable});
@override
_RecordPageState createState() => new _RecordPageState(myStateVariable: myvVariable);
}
class _RecordPageState extends State<RecordPage> {
int myStateVariable;
_RecordPageState({required this.myStateVariable});
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(
"your initiating variable is " + widget.myvVariable.toString(),
),
Text(
"your state variable is " + myStateVariable.toString(),
),
InkWell(
onTap: (){
setState(() {
myStateVariable++;
});
},
child: new Container(
child: Center(
child: new Text(
"increase the variable",
),
),
),
)
],
);
}
}
Upvotes: 1
Reputation: 22437
Yes, there is widget
:
From Doc:
/// The current configuration. /// /// A [State] object's configuration is the corresponding [StatefulWidget] /// instance. This property is initialized by the framework before calling /// [initState]. If the parent updates this location in the tree to a new /// widget with the same [runtimeType] and [Widget.key] as the current /// configuration, the framework will update this property to refer to the new /// widget and then call [didUpdateWidget], passing the old configuration as /// an argument. T get widget => _widget; T _widget;
Code should look like below:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: MyHomePage('John', 'Morison'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage(this.fname, this.lname);
final String fname;
final String lname;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Hello ${widget.fname} ${widget.lname}'),
)
);
}
}
Upvotes: 15