I have created a custom widget to get input from the user. I am using TextFields and TextEditingController to get this input. Here is the code for the custom widget called NewAddress:
import 'package:flutter/material.dart';
class NewAddress extends StatefulWidget {
const NewAddress({super.key}); // this is the constructor
@override
State<NewAddress> createState() {
return _NewAddressState();
}
}
class _NewAddressState extends State<NewAddress> {
final _address1Controller = TextEditingController();
final _address2Controller = TextEditingController();
final _cityController = TextEditingController();
final _stateController = TextEditingController();
final zipController = TextEditingController();
@override
void dispose() {
_address1Controller.dispose();
_address2Controller.dispose();
_cityController.dispose();
_stateController.dispose();
zipController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
TextField(
keyboardType: TextInputType.streetAddress,
controller: _address1Controller,
decoration: const InputDecoration(
label: Text(
'Address 1',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
TextField(
keyboardType: TextInputType.streetAddress,
controller: _address2Controller,
decoration: const InputDecoration(
label: Text(
'Address 2',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
TextField(
keyboardType: TextInputType.text,
controller: _cityController,
decoration: const InputDecoration(
label: Text(
'City',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
TextField(
keyboardType: TextInputType.text,
controller: _stateController,
decoration: const InputDecoration(
label: Text(
'State',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
TextField(
keyboardType: TextInputType.number,
controller: zipController,
decoration: const InputDecoration(
label: Text(
'Zip',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
],
),
);
}
}
I use this widget in the initial app screen called StartScreen. Here is the code for StartScreen:
import 'package:flutter/material.dart';
import '../screens/widgets/address_input.dart';
import '../screens/data_screen.dart';
class StartScreen extends StatelessWidget {
const StartScreen({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const NewAddress(),
OutlinedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DataScreen(zipController.text)));
},
style: OutlinedButton.styleFrom(
backgroundColor: Colors.blue, alignment: Alignment.center),
icon: const Icon(Icons.dataset, color: Colors.black, size: 30),
label: const Text(
'GET PROPERTY',
style: TextStyle(color: Colors.black, fontSize: 30),
),
),
],
),
);
}
}
I am getting an error on this line before I run the code: MaterialPageRoute(
builder: (context) => DataScreen(zipController.text)));
The line is under zipController and here is the error message: "Undefined name ‘zipController’."
I think I am getting it because I am not accessing the zipController in the right way.
I have tried this: MaterialPageRoute(
builder: (context) => DataScreen(NewAddress.zipController.text)));
but I still get an error but this time this is the error message:
The getter ‘zipController’ isn’t defined for the type ‘NewAddress’.
but as you can see in the code, I have imported the file where NewAddress and zipController are defined.
What am I doing wrong?
2
Answers
The issue you’re facing is related to how you’re trying to access the zipController variable from the NewAddress class. The zipController is an instance variable of the _NewAddressState class within the NewAddress widget, so you can’t directly access it using the widget class itself.
Instead, you need to pass the zipController instance to the DataScreen widget when you create it. Here’s how you can modify your code to achieve this:
Add a constructor to your NewAddress widget to pass the zipController to the parent widget (in this case, StartScreen).
Modify your StartScreen widget to pass the zipController to the NewAddress widget.
Bypassing the zipController instance to the NewAddress widget and then using it to create the DataScreen widget, you should be able to resolve the "Undefined name ‘zipController’" error. This way, you’re maintaining the proper scope for the zipController variable.
You should do something few changes. I added comments on what you should change. Customize everything as yourself.
Here is your NewAddress widget. I showed here only one example.
And finally, your DataScreen should be like this.