I'm making a authentication login form then I face this error - flutter

I'm making authentication login form and want to connect submitAuthForm Function to the AuthForm. That's why I pass reference in the AuthForm. I am beginner. Please help me to solve this problem (The argument type void Function(String, String, String, bool) can't be assigned to the parameter type void Function(String, String, String, bool)
Thanks.
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
void _submitAuthForm(
String email,
String password,
String username,
bool isLogin) {
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Authform(_submitAuthForm,)/*( The argument type 'void Function(String, String, String, bool)' can't be assigned to the parameter type 'Void Function(String, String, String, bool)'.*/)
);
}
}
class Authform extends StatefulWidget {
Authform(this.submitFN);
final Void Function(
String email, String password, String username, bool isLogin) submitFN;
#override
_AuthformState createState() => _AuthformState();
}
class _AuthformState extends State<Authform> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail;
var _userName;
var _userPassword;
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState!.save();
widget.submitFN(_userEmail,_userPassword,_userName,_isLogin);
}
}
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value!.isEmpty || !value.contains('#')) {
return 'please enter valid email address';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.mail,
color: Colors.orange,
),
labelText: 'Email Addess'),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Username is short enter atleast 4 characters ';
}
},
decoration: InputDecoration(
icon: Icon(
Icons.person,
color: Colors.orange,
),
labelText: 'Username'),
onSaved: (value) {
_userName = value;
},
),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value!.isEmpty || value.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
decoration: InputDecoration(
icon: Icon(
Icons.lock,
color: Colors.orange,
),
labelText: 'password',
),
obscureText: true,
onSaved: (value) {
_userPassword = value;
},
),
SizedBox(
height: 12,
),
ElevatedButton(
onPressed: _trySubmit,
child: Text(_isLogin ? 'Login' : 'Signup'),
style: ElevatedButton.styleFrom(onPrimary: Colors.white),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create new account'
: 'I already have a acoount'))
],
)),
)),
),
);
}
}

When declaring a function or variable you have follow proper declaring method to avoid unusual issues. You have declare your function using Void the V is in capital case there but it must be in small case like void. Juts change this like :
final Void Function(
to
final void Function(

import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(),
home: AuthScreen(),
);
}
}
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
void _submitAuthForm(
String email, String password, String username, bool isLogin) {}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Authform(
_submitAuthForm,
));
}
}
class Authform extends StatefulWidget {
Authform(this.submitFN);
final void Function(
String email, String password, String username, bool isLogin) submitFN;
#override
_AuthformState createState() => _AuthformState();
}
class _AuthformState extends State<Authform> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail;
var _userName;
var _userPassword;
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState!.save();
widget.submitFN(_userEmail, _userPassword, _userName, _isLogin);
}
}
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value!.isEmpty || !value.contains('#')) {
return 'please enter valid email address';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.mail,
color: Colors.orange,
),
labelText: 'Email Addess'),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Username is short enter atleast 4 characters ';
}
},
decoration: InputDecoration(
icon: Icon(
Icons.person,
color: Colors.orange,
),
labelText: 'Username'),
onSaved: (value) {
_userName `enter code here`= value;
},
),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value!.isEmpty || value.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
decoration: InputDecoration(
icon: Icon(
Icons.lock,
color: Colors.orange,
),
labelText: 'password',
),
obscureText: true,
onSaved: (value) {
_userPassword = value;
},
),
SizedBox(
height: 12,
),
ElevatedButton(
onPressed: _trySubmit,
child: Text(_isLogin ? 'Login' : 'Signup'),
style: ElevatedButton.styleFrom(onPrimary: Colors.white),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create new account'
: 'I already have a acoount'))
],
)),
)),
),
);
}
}

account_screen.dart
child: AuthForm(
submitFn: _submitAuthForm,
),

Related

I am new to programming can someone help me what's the problem here, I was doing a login page and this happens

If password and username is same, I want to print 'username and password is same' statement in the terminal .But it is only printing the second statement 'username and password does not match even if username and password is same or not . I don't understand why this happened somebody help, I am new here' ( NB : problem is inside the function named checkLogin)
class ScreenLogin extends StatefulWidget {
ScreenLogin({Key? key}) : super(key: key);
#override
State<ScreenLogin> createState() => _ScreenLoginState();
}
class _ScreenLoginState extends State<ScreenLogin> {
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
bool _isDataMatched = false;
final _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextFormField(
controller: _usernameController,
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: 'Username'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'value is empty';
} else {
return null;
}
},
),
const SizedBox(
height: 20,
),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: 'Password'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'value is empty';
} else {
return null;
}
}),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: _isDataMatched,
child: Text(
'Username and password does not match',
style: TextStyle(color: Colors.red),
),
),
ElevatedButton.icon(
onPressed: () {
if (_formkey.currentState!.validate()) {
checkLogin(context);
} else {
print('Data Empty');
}
},
icon: const Icon(Icons.check),
label: const Text('Login ')),
],
)
],
),
),
),
));
}
void checkLogin(BuildContext context) {
final _username = _usernameController;
final _password = _passwordController;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}
}
To get text, you need to use .text on controller.
_usernameController.text;
void checkLogin(BuildContext context) {
final _username = _usernameController.text;
final _password = _passwordController.text;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}
In login check you should do this:
void checkLogin(BuildContext context) {
final _username = _usernameController.text;
final _password = _passwordController.text;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}

Flutter: Radio and Switch buttons isn't updating inside a listview.builder, but it works outside

I'm using a form to create multiples vehicle entries.
every time I click on the floating button it adds a vehicleform to the page one on top of the other. "A List type that receives widgets"
If I try to select the "leased radio option", the form doesn't update, and if hit the switch button right below, nothing happens again. BUT! Curiously if I hit any of the Dropdown State....it works for them (only the dropdown gets updated). and BUT! number 2: If I hit the floating button to add a new vehicle form, the changes made on the previous form gets carried to the new form. My theory is that the buttons are working under the hood, but the setStates are no running correctly
On the main_page.dart there is a stateful widget that calls vehicles_page() which holds all the scaffold and widgets for that form including a dropdown list which is called from a 3rd file(dropdown_forms.dart).
To guide towards the right direction, just lay your eyes at the end of the code on the build() function.
FYI - Flutter Doctor -v returned no errors
Yes -I'm using stateful widgets
Yes - I'm using setstates to update
No - I'm not a professional programmer, I'm a super beginner on flutter and this is my 3rd week playing with flutter
After running some tests.... if I remove them from the listview widget, it works fine.
main.dart
This is the main file
import 'package:flutter/material.dart';
import 'package:learningflutter/screens/parties_page.dart';
import 'package:learningflutter/screens/vehicles_page.dart';
import 'package:learningflutter/screens/incident_page.dart';
// import 'package:learningflutter/parties.dart';
enum VehicleType { pov, leased, pgti }
void main(List<String> args) {
runApp(const VortexEHS());
}
class VortexEHS extends StatelessWidget {
const VortexEHS({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'VortexEHS',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: _MainPage(),
);
}
}
class _MainPage extends StatefulWidget {
_MainPage({Key? key}) : super(key: key);
#override
State<_MainPage> createState() => __MainPageState();
}
class __MainPageState extends State<_MainPage> {
// int currentPageIndex = 1;
final screens = [
PartiesPage(),
VehiclesPage(),
FormIncident(),
FormIncident()
];
#override
Widget build(BuildContext context) {
return Container(child: VehiclesPage());
}
}
vehicles_page.dart (Code Below)
// ignore_for_file: unused_element, unused_field
import 'package:flutter/material.dart';
import '../dropdown_forms.dart';
enum VehicleType { pov, leased, pgti }
class VehiclesPage extends StatefulWidget {
const VehiclesPage({Key? key}) : super(key: key);
#override
State<VehiclesPage> createState() => _VehiclesPageState();
}
class _VehiclesPageState extends State<VehiclesPage> {
//Variables
VehicleType vehicleType = VehicleType.pov;
bool isCommercial = false;
String? _make;
String? _model;
String? _year;
String? _color;
String? _vimNumber;
String? _plate;
String? _ownerName;
String? _ownerAddress;
String? _ownerCity;
String? _ownerState;
String? _ownerZip;
String? _ownerPhone;
String? _insuranceCoName;
String? _insuranceCoPhone;
String? _policyHolderName;
String? _policyNumber;
List<Widget> vehicles = [];
Widget buildTypeVeihicle() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text('POV'),
leading: Radio(
value: VehicleType.pov,
groupValue: vehicleType,
onChanged: (VehicleType? value) {
setState(() {
vehicleType = value!;
});
}),
),
),
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text('Leased'),
leading: Radio(
value: VehicleType.leased,
groupValue: vehicleType,
onChanged: (VehicleType? value) {
setState(() {
vehicleType = value!;
});
}),
),
),
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text(
'PGTI',
softWrap: false,
),
leading: Radio(
value: VehicleType.pgti,
groupValue: vehicleType,
onChanged: (VehicleType? value) {
setState(() {
vehicleType = value!;
});
}),
),
),
],
);
}
Widget _buildIsCommercial() {
return SwitchListTile(
title: const Text('This is commercial vehicle?'),
value: isCommercial,
onChanged: (bool value) {
setState(() {
isCommercial = value;
});
},
// secondary: const Icon(Icons.car_repair),
);
}
Widget _buildVehicleMake() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Make'),
validator: (String? value) {
if (value == null) {
return 'Make is required';
}
return null;
},
onSaved: (String? value) {
_make = value;
},
);
}
Widget _buildVehicleModel() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Model'),
validator: (String? value) {
if (value == null) {
return 'Model is required';
}
return null;
},
onSaved: (String? value) {
_model = value;
},
);
}
Widget _buildVehicleYear() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Year'),
validator: (String? value) {
if (value == null) {
return 'Year is required';
}
return null;
},
onSaved: (String? value) {
_year = value;
},
);
}
Widget _buildVehicleColor() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Color'),
validator: (String? value) {
if (value == null) {
return 'Color is required';
}
return null;
},
onSaved: (String? value) {
_color = value;
},
);
}
Widget _buildVehicleVinNumber() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Vin Number'),
validator: (String? value) {
if (value == null) {
return 'Vin Number is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildVehiclePlate() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Plate Number'),
validator: (String? value) {
if (value == null) {
return 'Plate Number is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildOwnerName() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner Name'),
validator: (String? value) {
if (value == null) {
return 'Owner Name is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildOwnerAddress() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner Address'),
validator: (String? value) {
if (value == null) {
return 'Owner Address is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildOwnerCity() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner City'),
validator: (String? value) {
if (value == null) {
return 'Owner City is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildOwnerZip() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner Zip'),
validator: (String? value) {
if (value == null) {
return 'Owner Zip is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildOwnerPhone() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner Phone'),
validator: (String? value) {
if (value == null) {
return 'Owner Phone is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildInsuranceCo() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Owner Insurance Company'),
validator: (String? value) {
if (value == null) {
return 'Owner Insurance Company is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
// ignore: unused_element
Widget _buildInsurancePhone() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Insurance Phone'),
validator: (String? value) {
if (value == null) {
return 'Insurance Phone is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildPolicyHolderName() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Policy Holder'),
validator: (String? value) {
if (value == null) {
return 'Policy Holder is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildPolicyNumber() {
return TextFormField(
decoration: const InputDecoration(labelText: 'Policy Number'),
validator: (String? value) {
if (value == null) {
return 'Policy Number is required';
}
return null;
},
onSaved: (String? value) {
_vimNumber = value;
},
);
}
Widget _buildVehiclesCard() {
return Container(
margin: const EdgeInsets.all(8.0),
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(color: Colors.blueGrey, blurRadius: 10, spreadRadius: -10)
],
),
child: Card(
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Container(
margin: const EdgeInsets.fromLTRB(0, 0, 0, 10),
padding: const EdgeInsets.all(10),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Icon(Icons.directions_car, color: Colors.teal),
IconButton(
onPressed: () {
setState(() {
print('Trash presses');
});
},
icon: const Icon(Icons.delete),
color: Colors.red,
),
],
),
buildTypeVeihicle(),
_buildIsCommercial(),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: _buildVehicleMake()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: _buildVehicleModel()))
]),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: _buildVehicleYear()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: _buildVehicleColor()))
]),
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(child: _buildVehicleVinNumber()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8.0, 0, 0, 0),
child: _buildVehiclePlate(),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 20, 0, 0),
child: DropdownStatesUs())),
]),
const SizedBox(
height: 8,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: const [
Icon(
Icons.person,
color: Colors.teal,
),
],
),
Row(
children: [
Expanded(child: _buildOwnerName()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: _buildOwnerPhone(),
)),
],
),
_buildOwnerAddress(),
Row(
children: [
Expanded(child: _buildOwnerCity()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 20, 0, 0),
child: DropdownStatesUs(),
)),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: _buildOwnerZip(),
)),
],
),
Row(
children: [
Expanded(child: _buildPolicyHolderName()),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
child: _buildPolicyNumber(),
)),
],
)
],
),
),
),
);
}
//
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.teal,
child: const Icon(Icons.add),
onPressed: () {
vehicles.add(_buildVehiclesCard());
// print(vehicles.length);
setState(() {});
},
),
body: Form(
child: ListView.builder(
primary: false,
itemCount: vehicles.length,
itemBuilder: (BuildContext context, int i) {
return vehicles[i];
},
),
),
);
}
}
Thanks for any help beforehand, any other advices or tips to make the code better, let me know
The current state changes behavior reflected on newly item because last item created before the radio-buttom or switch tile was changed. Once you switch the button and change the radioGroup value it will only get to the new created widget that will be trigger by floating action button.
Notice that List<Widget> vehicles = []; holds the created widgets. And while creating new widget you are using state variables like vehicleType and isCommercial. Once you click on 1st generated widget, these variables get new data based on your tap event. while the state is holding these variables, then again you click on fab to add item on vehicles to generate item with current state of vehicleType and isCommercial.
While every list-item will have its own state, it is better to create a new StatefulWidget for each item. Also, you can go for state-management like riverpod, bloc for future purpose.
A simplify version but not complete, you need to handle callback to get changes data or better start using riverpod or bloc for state management
enum VehicleType { pov, leased, pgti }
class VehiclesPage extends StatefulWidget {
const VehiclesPage({Key? key}) : super(key: key);
#override
State<VehiclesPage> createState() => _VehiclesPageState();
}
class _VehiclesPageState extends State<VehiclesPage> {
List<MyDataModel> vehicles = [];
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.teal,
child: const Icon(Icons.add),
onPressed: () {
vehicles.add(MyDataModel());
setState(() {});
},
),
body: Form(
child: ListView.builder(
primary: false,
itemCount: vehicles.length,
itemBuilder: (BuildContext context, int i) {
return ListItem(model: vehicles[i]);
},
),
),
);
}
}
class MyDataModel {
final VehicleType vehicleType;
final bool isCommercial;
MyDataModel({
this.vehicleType = VehicleType.pov,
this.isCommercial = false,
});
MyDataModel copyWith({
VehicleType? vehicleType,
bool? isCommercial,
}) {
return MyDataModel(
vehicleType: vehicleType ?? this.vehicleType,
isCommercial: isCommercial ?? this.isCommercial,
);
}
}
class ListItem extends StatefulWidget {
final MyDataModel model;
const ListItem({
Key? key,
required this.model,
}) : super(key: key);
#override
State<ListItem> createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
late MyDataModel model = widget.model;
Widget buildTypeVeihicle() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text('POV'),
leading: Radio(
value: VehicleType.pov,
groupValue: model.vehicleType,
onChanged: (VehicleType? value) {
setState(() {
model = model.copyWith(vehicleType: value);
});
}),
),
),
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text('Leased'),
leading: Radio(
value: VehicleType.leased,
groupValue: model.vehicleType,
onChanged: (VehicleType? value) {
setState(() {
model = model.copyWith(vehicleType: value);
});
}),
),
),
Expanded(
child: ListTile(
horizontalTitleGap: 0,
dense: true,
title: const Text(
'PGTI',
softWrap: false,
),
leading: Radio(
value: VehicleType.pgti,
groupValue: model.vehicleType,
onChanged: (VehicleType? value) {
setState(() {
model = model.copyWith(vehicleType: value);
});
}),
),
),
],
);
}
Widget _buildIsCommercial() {
return SwitchListTile(
title: const Text('This is commercial vehicle?'),
value: model.isCommercial,
onChanged: (bool value) {
setState(() {
model = model.copyWith(isCommercial: value);
});
},
// secondary: const Icon(Icons.car_repair),
);
}
Widget _buildVehiclesCard() {
return Container(
margin: const EdgeInsets.all(8.0),
decoration: const BoxDecoration(
boxShadow: [
BoxShadow(color: Colors.blueGrey, blurRadius: 10, spreadRadius: -10)
],
),
child: Card(
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: Container(
margin: const EdgeInsets.fromLTRB(0, 0, 0, 10),
padding: const EdgeInsets.all(10),
child: Column(
children: [
buildTypeVeihicle(),
_buildIsCommercial(),
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return _buildVehiclesCard();
}
}

type 'Null' is not a subtype of type 'File' of 'image' flutter problem

I uploaded my image to FireStore. When I am creating an image it's perfectly ok everything uploading perfectly. After SignUp I can easily go to the user profile and can see the user name and email. But when I log out from the user profile and from my LOGIN from when providing existing email and password which I have created already then the Exception is thrown. I am not getting the issue. Exception has occurred.
_TypeError (type 'Null' is not a subtype of type 'File' of 'image')
import 'dart:io';
import '../picker/user_image_picker.dart';
import 'package:flutter/material.dart';
class AuthForm extends StatefulWidget {
AuthForm(this.submitFn, this.isLoading);
final bool isLoading;
var submitFn;
void function(
String email,
String password,
String userName,
File image,
bool isLogin,
BuildContext ctx,
);
#override
_AuthFormState createState() => _AuthFormState();
#override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail = '';
var _userName = '';
var _userPasssword = '';
File? userImageFile;
void pickedImage(File image) {
userImageFile = image;
}
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (userImageFile == null && !_isLogin) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Please Pick an Image.'),
backgroundColor: Theme.of(context).errorColor,
),
);
return;
}
if (isValid) {
_formKey.currentState?.save();
print(_userEmail);
print(_userName);
print(_userPasssword);
print(' Good to go ');
widget.submitFn(
_userEmail.trim(),
_userPasssword.trim(),
_userName.trim(),
userImageFile,
_isLogin,
context,
);
} else {
print('Form is not valid');
}
}
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (!_isLogin) UserImagePicker(pickedImage),//this is my image file
TextFormField(
key: ValueKey('email'),
onSaved: (value) {
_userEmail = value!;
},
validator: (value) {
if (value!.isEmpty ||
!value.contains(RegExp(
'^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]+.[com]'))) {
return 'enter valid Email';
//print('Email validation is not ok');
} else {
return null;
}
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email Address', icon: Icon(Icons.email)),
),
if (!_isLogin)
TextFormField(
key: ValueKey('userName'),
onSaved: (value) {
_userName = value!;
},
validator: (value) {
if (value == null || value.length < 4) {
return 'Enter At least 4 charaters ';
}
return null;
},
decoration: InputDecoration(
labelText: 'User Name', icon: Icon(Icons.person)),
),
TextFormField(
key: ValueKey('password'),
onSaved: (value) {
_userPasssword = value!;
},
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty || value.length < 7) {
return 'Enter at least 7 Digits';
}
return null;
},
decoration: InputDecoration(
labelText: 'Password',
icon: Icon(
Icons.security,
),
),
),
SizedBox(
height: 20,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
ElevatedButton(
child: Text(_isLogin ? 'Login' : 'Signup'),
onPressed: _trySubmit,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
TextButton(
style: TextButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
child: Text(_isLogin
? 'Create New Account'
: 'I already have an account'),
onPressed: () {
setState(
() {
_isLogin = !_isLogin;
},
);
},
)
],
),
),
),
),
);
}
}
Looks like userImageFile is null. This happen because this variable is nullable, and when it gets passed to submitFn (which weirdly is a dynamic variable...?) it throws, because it expects a non-nullable image parameter.

Pushing(sending) a single variable to new Class with multiple arguments

I'm trying to push kombiController.text value to a new class, but after trying all sorts of things, I just don't know what else to do. I'm getting an error "8 positional arguments expected, but found 0, which I'm guessing is due to my FeedbackForm class requiring 8, but I don't find solution to how to fix it or set up some default paramaters.
Note: The other variable message-ekipaController is getting sent normally and I had no troubles implementing it.
I've been trying to fix and find a solution to this "little" problem for 2 days now and no matter from which angle I try to resolve this issue, I just get new problems somewhere else.
mainscreen.dart
import 'package:flutter/material.dart';
import 'secondscreen.dart';
import 'models/feedback_form.dart';
import 'package:flutter/widgets.dart';
class MainScreen extends StatefulWidget {
MainScreen({Key key}) : super(key: key);
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
String kombi;
String valuePolja;
TextEditingController ekipaController = new TextEditingController();
TextEditingController kombiController = new TextEditingController();
// Default Drop Down Item.
String dropdownValue = 'Tom Cruise';
// To show Selected Item in Text.
String holder = '' ;
List listItem = [
"1", "2", "3", "4", "5"
];
void getDropDownItem(){
setState(() {
holder = dropdownValue ;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("DHL"),
),
body: Center(
child: Column(
children: <Widget> [
TextFormField(
controller: ekipaController,
onChanged: (text) {
valuePolja = text;
},
validator: (value){
if(value.isEmpty){
return "Enter Valid Name";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Ime Ekipe",
),
),
DropdownButton(
hint: Text("Izberi Kombi: "),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
value: kombi,
onChanged: (newValue) {
setState(() {
kombi = newValue;
});
kombiController.text = newValue;
},
items: listItem.map((valueItem) {
return DropdownMenuItem(
value: valueItem,
child: Text(valueItem),
);
}).toList(),
),
Padding(
padding: EdgeInsets.only(top: 30, bottom: 30),
child :
//Printing Item on Text Widget
Text('Selected Item = ' + kombiController.text,
style: TextStyle (fontSize: 22, color: Colors.black))),
ElevatedButton(
child: Text('Next Screen',
style: TextStyle(
color: Colors.white,
),
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SecondScreen(message: ekipaController.text)));
Navigator.push(context,
MaterialPageRoute(builder: (context) => FeedbackForm(kombiController: kombiController.text)));
}
),
],
),
)
);
}
}
feedback_form.dart
import 'package:dhl_app/mainscreen.dart';
import 'package:flutter/widgets.dart';
class FeedbackForm extends StatefulWidget {
const FeedbackForm(this.ime_ekipe, this.ime_stranke, this.postna_stevilka, this.teza, this.type, this.datum, this.dostavljeno, this.kombiController);
final String kombiController;
final String ime_ekipe;
final String ime_stranke;
final String postna_stevilka;
final String teza;
final String type;
final String datum;
final String dostavljeno;
//FeedbackForm(this._ime_ekipe, this._ime_stranke, this._postna_stevilka, this._teza, this._type, this._datum, this._dostavljeno, this.kombiController);
String toParams() => "?ime_ekipe=$ime_ekipe&ime_stranke=$ime_stranke&postna_stevilka=$postna_stevilka&teza=$teza&type=$type&datum=$datum&dostavljeno=$dostavljeno&kombi=$kombiController";
#override
State<StatefulWidget> createState() {
// TODO: implement createState
throw UnimplementedError();
}
}
secondscreen.dart (where the other variable works)
import 'package:flutter/material.dart';
import 'models/controller.dart';
import 'models/feedback_form.dart';
import 'mainscreen.dart';
class SecondScreen extends StatefulWidget {
final String message;
const SecondScreen({Key key, this.message}) : super(key: key);
#override
_SecondScreen createState() => _SecondScreen();
}
class _SecondScreen extends State<SecondScreen> {
var _controller = TextEditingController();
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
//TextField Controllers
TextEditingController nameController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController phoneNumberController = TextEditingController();
TextEditingController feedbackController = TextEditingController();
TextEditingController typeController = TextEditingController();
TextEditingController dateController = TextEditingController();
TextEditingController dostavljenoController = TextEditingController();
TextEditingController kombiController = TextEditingController();
void _submitForm(){
if(_formKey.currentState.validate()) {
FeedbackForm feedbackForm = FeedbackForm(
nameController.text,
emailController.text,
phoneNumberController.text,
feedbackController.text,
typeController.text,
dateController.text,
dostavljenoController.text,
kombiController.text,
);
FormController formController = FormController(
(String response) {
print(response);
if(response == FormController.STATUS_SUCCESS){
_showSnackBar("Feedback Submitted!");
}else {
_showSnackBar("Error Occured!");
}
});
_showSnackBar("Submitting Feedback");
formController.submitForm(feedbackForm);
}
}
_showSnackBar(String message) {
final snackBar = SnackBar(content: Text(message),);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Vnesi Podatke"),
),
key: _scaffoldKey,
body: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.symmetric(vertical: 50, horizontal: 24),
child: Column(
children: <Widget> [
TextFormField(
controller: nameController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Name";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "${widget.message}",
suffixIcon: IconButton(
onPressed: () => nameController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: emailController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Email";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Ime Stranke",
suffixIcon: IconButton(
onPressed: () => emailController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: phoneNumberController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Mobile Number";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Poštna Številka",
suffixIcon: IconButton(
onPressed: () => phoneNumberController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: feedbackController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Feedback";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Kilogramov",
suffixIcon: IconButton(
onPressed: () => feedbackController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: typeController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Feedback";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Tip",
suffixIcon: IconButton(
onPressed: () => typeController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: dateController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Feedback";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Datum",
suffixIcon: IconButton(
onPressed: () => dateController.clear(),
icon: Icon(Icons.clear),
),
),
),
TextFormField(
controller: dostavljenoController,
validator: (value){
if(value.isEmpty){
return "Enter Valid Feedback";
}else{
return null;
}
},
decoration: InputDecoration(
hintText: "Dostavljeno",
suffixIcon: IconButton(
onPressed: () => dostavljenoController.clear(),
icon: Icon(Icons.clear),
),
),
),
RaisedButton(
color: Colors.blue,
textColor: Colors.white,
onPressed: _submitForm,
child: Text('Submit Feedback'),
)
],
)
),
)
);
}
}

How to pass the data from the form to the next screen in flutter?

I'm building an application that has a pretty long form with a lot of text fields, so I divided the text fields into multiple screens. It got three screens, the first screen has some common text fields such as phone, website, email, etc. The second screen has some more text fields and the same with the third screen. I'm trying to display all the details from the three forms at the end on a different screen.
I want to display all the details in the end when I hit the 'Done' button on a different page.
Here's the code for the first screen which has the first form:-
import 'package:flutter/material.dart';
import 'package:instaskool/model.dart';
import 'package:validators/validators.dart' as validator;
import 'package:instaskool/home_screens/homescreen_student.dart';
import 'package:instaskool/home_screens/homescreen_school.dart';
import 'package:instaskool/screens/school_signup_two.dart';
class SchoolReg extends StatefulWidget {
#override
_SchoolRegState createState() => _SchoolRegState();
}
class _SchoolRegState extends State<SchoolReg> {
final _formKey = GlobalKey<FormState>();
School school = School();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 130),
alignment: Alignment.topCenter,
child: MyTextFormField(
hintText: 'School name',
validator: (String value) {
if (value.isEmpty) {
return 'Enter your school name';
}
return null;
},
onSaved: (String value) {
school.schoolName = value;
},
),
),
MyTextFormField(
hintText: 'Phone',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the phone number';
}
return null;
},
onSaved: (String value) {
school.schoolPhone = value;
},
),
MyTextFormField(
hintText: 'Email',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the email address';
}
return null;
},
onSaved: (String value) {
school.schoolEmail = value;
},
),
MyTextFormField(
hintText: 'School Website',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the school's website";
}
return null;
},
onSaved: (String value) {
school.schoolWebsite = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SchoolRegTwo()));
}
},
child: Text(
'Next',
style: TextStyle(
color: Colors.white,
),
),
)
],
),
),
),
);
}
}
class MyTextFormField extends StatelessWidget {
final String hintText;
final Function validator;
final Function onSaved;
final bool isPassword;
final bool isEmail;
MyTextFormField({
this.hintText,
this.validator,
this.onSaved,
this.isPassword = false,
this.isEmail = false,
});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.all(15.0),
border: InputBorder.none,
filled: true,
fillColor: Colors.grey[200],
),
obscureText: isPassword ? true : false,
validator: validator,
onSaved: onSaved,
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
),
);
}
}
Here's the code for the second form:-
import 'package:flutter/material.dart';
import 'package:instaskool/model.dart';
import 'package:validators/validators.dart' as validator;
import 'package:instaskool/home_screens/homescreen_student.dart';
import 'package:instaskool/home_screens/homescreen_school.dart';
import 'package:instaskool/screens/school_signup_three.dart';
class SchoolRegTwo extends StatefulWidget {
#override
_SchoolRegTwoState createState() => _SchoolRegTwoState();
}
class _SchoolRegTwoState extends State<SchoolRegTwo> {
final _formKey = GlobalKey<FormState>();
SchoolDet schooldet = SchoolDet();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 130),
alignment: Alignment.topCenter,
child: MyTextFormField(
hintText: 'School address 1',
validator: (String value) {
if (value.isEmpty) {
return "Enter your school's address";
}
return null;
},
onSaved: (String value) {
schooldet.addressOne = value;
},
),
),
MyTextFormField(
hintText: 'School address 2',
validator: (String value) {
if (value.isEmpty) {
return "Enter the school's address";
}
return null;
},
onSaved: (String value) {
schooldet.addressTwo = value;
},
),
MyTextFormField(
hintText: 'City',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the city';
}
return null;
},
onSaved: (String value) {
schooldet.city = value;
},
),
MyTextFormField(
hintText: 'Pincode',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the pincode";
}
return null;
},
onSaved: (String value) {
schooldet.pincode = value;
},
),
MyTextFormField(
hintText: 'State',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the state";
}
return null;
},
onSaved: (String value) {
schooldet.state = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SchoolRegThree(schooldet: this.schooldet)));
}
},
child: Text(
'Next',
style: TextStyle(
color: Colors.white,
),
),
)
],
),
),
),
);
}
}
class MyTextFormField extends StatelessWidget {
final String hintText;
final Function validator;
final Function onSaved;
final bool isPassword;
final bool isEmail;
MyTextFormField({
this.hintText,
this.validator,
this.onSaved,
this.isPassword = false,
this.isEmail = false,
});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.all(15.0),
border: InputBorder.none,
filled: true,
fillColor: Colors.grey[200],
),
obscureText: isPassword ? true : false,
validator: validator,
onSaved: onSaved,
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
),
);
}
}
Here's the code for the third form:-
import 'package:flutter/material.dart';
import 'package:instaskool/model.dart';
import 'package:validators/validators.dart' as validator;
import 'package:instaskool/home_screens/homescreen_student.dart';
import 'package:instaskool/home_screens/homescreen_school.dart';
import 'package:instaskool/screens/school_signup_three.dart';
import 'package:instaskool/screens/school_code.dart';
class SchoolRegThree extends StatefulWidget {
School school;
SchoolRegThree({this.school, SchoolDet schooldet});
#override
_SchoolRegThreeState createState() => _SchoolRegThreeState();
}
class _SchoolRegThreeState extends State<SchoolRegThree> {
final _formKey = GlobalKey<FormState>();
SchoolUser schooluser = SchoolUser();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 100),
child: MyTextFormField(
hintText: 'Username',
isPassword: true,
validator: (String value) {
if (value.length < 5) {
return 'Username should be at least 5 characters long';
}
_formKey.currentState.save();
return null;
},
onSaved: (String value) {
schooluser.username = value;
},
),
),
MyTextFormField(
hintText: 'New Password',
isPassword: true,
validator: (String value) {
if (value.length < 7) {
return 'Password should be at least 7 characters long';
} else if (schooluser.password != null) {
print(value);
print(schooluser.password);
}
return null;
},
onSaved: (String value) {
schooluser.password = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultSchool(schooluser: this.schooluser)));
}
},
child: Text(
'Done',
style: TextStyle(
color: Colors.white,
),
),
)
],
),
),
),
);
}
}
class MyTextFormField extends StatelessWidget {
final String hintText;
final Function validator;
final Function onSaved;
final bool isPassword;
final bool isEmail;
MyTextFormField({
this.hintText,
this.validator,
this.onSaved,
this.isPassword = false,
this.isEmail = false,
});
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(8.0),
child: TextFormField(
decoration: InputDecoration(
hintText: hintText,
contentPadding: EdgeInsets.all(15.0),
border: InputBorder.none,
filled: true,
fillColor: Colors.grey[200],
),
obscureText: isPassword ? true : false,
validator: validator,
onSaved: onSaved,
keyboardType: isEmail ? TextInputType.emailAddress : TextInputType.text,
),
);
}
}
Here's the model.dart which has all the variables:-
import 'package:flutter/material.dart';
import 'package:instaskool/screens/school_code.dart';
class Model {
String fullname;
String code;
String standard;
String section;
String username;
String password;
Model({this.fullname, this.code, this.standard, this.section, this.username, this.password});
}
class School {
String schoolName;
String schoolPhone;
String schoolEmail;
String schoolWebsite;
School({this.schoolName, this.schoolPhone, this.schoolEmail, this.schoolWebsite});
}
class SchoolDet {
String addressOne;
String addressTwo;
String city;
String pincode;
String state;
SchoolDet({this.addressOne, this.addressTwo, this.city, this.pincode, this.state});
}
class SchoolUser{
String username;
String password;
SchoolUser({this.username, this.password});
}
class SchoolCode{
String principalCode;
String teacherCode;
String studentCode;
SchoolCode({this.principalCode, this.teacherCode, this.studentCode});
}
Here's the result screen where I wanna display all the data:-
import 'package:flutter/material.dart';
import 'package:instaskool/model.dart';
class ResultSchool extends StatelessWidget {
School school;
SchoolDet schooldet;
SchoolCode schoolcode;
SchoolUser schooluser;
ResultSchool({this.school, this.schooldet, this.schooluser});
#override
Widget build(BuildContext context) {
return (Scaffold(
appBar: AppBar(title: Text('School details')),
body: Container(
margin: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(school.schoolName, style: TextStyle(fontSize: 22)),
Text(school.schoolPhone, style: TextStyle(fontSize: 22)),
Text(school.schoolEmail, style: TextStyle(fontSize: 22)),
Text(school.schoolWebsite, style: TextStyle(fontSize: 22)),
Text(schooldet.addressOne, style: TextStyle(fontSize: 22)),
Text(schooldet.addressTwo, style: TextStyle(fontSize: 22)),
Text(schooldet.city, style: TextStyle(fontSize: 22)),
Text(schooldet.pincode, style: TextStyle(fontSize: 22)),
Text(schooldet.state, style: TextStyle(fontSize: 22)),
Text(schooluser.username, style: TextStyle(fontSize: 22)),
Text(schooluser.password, style: TextStyle(fontSize: 22)),
Text(schoolcode.teacherCode, style: TextStyle(fontSize: 22)),
Text(schoolcode.principalCode, style: TextStyle(fontSize: 22)),
],
),
),
));
}
}
Add a widget to manage form transitions
enum SchoolFormPhase { BASIC_DTL, ADDRESS, USER_DTL }
class SchoolRegistration extends StatefulWidget {
#override
_SchoolRegistrationState createState() => _SchoolRegistrationState();
}
class _SchoolRegistrationState extends State<SchoolRegistration> {
SchoolFormPhase phase;
School schoolForm;
#override
void initState() {
phase = SchoolFormPhase.BASIC_DTL;
schoolForm = School();
super.initState();
}
#override
Widget build(BuildContext context) {
switch (phase) {
case SchoolFormPhase.BASIC_DTL:
return SchoolReg(
school: schoolForm,
onSaved: (school) {
setState(() {
schoolForm = school;
phase = SchoolFormPhase.ADDRESS;
});
});
case SchoolFormPhase.ADDRESS:
return SchoolRegTwo(
school: schoolForm,
onSaved: (school) {
setState(() {
schoolForm = school;
phase = SchoolFormPhase.USER_DTL;
});
});
case SchoolFormPhase.USER_DTL:
return SchoolRegThree(
school: schoolForm,
onSaved: (school) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultSchool(
schooluser: school.user,
school: school,
schooldet: school.address)));
},
);
}
return Container();
}
}
change the Form widget to accept inputs
class SchoolReg extends StatefulWidget {
final School school;
final Function(School) onSaved;
const SchoolReg({Key key, this.school, this.onSaved}) : super(key: key);
#override
_SchoolRegState createState() => _SchoolRegState();
}
class _SchoolRegState extends State<SchoolReg> {
final _formKey = GlobalKey<FormState>();
School _school;
#override
void initState() {
_school = widget.school;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 130),
alignment: Alignment.topCenter,
child: MyTextFormField(
hintText: 'School name',
validator: (String value) {
return value.isEmpty
? 'Enter your school name'
: null;
},
onSaved: (value) => _school.schoolName = value)),
MyTextFormField(
hintText: 'Phone',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the phone number';
}
return null;
},
onSaved: (String value) {
_school.schoolPhone = value;
},
),
MyTextFormField(
hintText: 'Email',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the email address';
}
return null;
},
onSaved: (String value) {
_school.schoolEmail = value;
},
),
MyTextFormField(
hintText: 'School Website',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the school's website";
}
return null;
},
onSaved: (String value) {
_school.schoolWebsite = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
widget.onSaved(_school);
}
},
child:
Text('Next', style: TextStyle(color: Colors.white)))
]))));
}
}
form 2
class SchoolRegTwo extends StatefulWidget {
final School school;
final Function(School) onSaved;
const SchoolRegTwo({Key key, this.school, this.onSaved}) : super(key: key);
#override
_SchoolRegTwoState createState() => _SchoolRegTwoState();
}
class _SchoolRegTwoState extends State<SchoolRegTwo> {
final _formKey = GlobalKey<FormState>();
SchoolDet schooldet;
#override
void initState() {
schooldet = widget.school.address;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 130),
alignment: Alignment.topCenter,
child: MyTextFormField(
hintText: 'School address 1',
validator: (String value) {
if (value.isEmpty) {
return "Enter your school's address";
}
return null;
},
onSaved: (String value) {
schooldet.addressOne = value;
},
),
),
MyTextFormField(
hintText: 'School address 2',
validator: (String value) {
if (value.isEmpty) {
return "Enter the school's address";
}
return null;
},
onSaved: (String value) {
schooldet.addressTwo = value;
},
),
MyTextFormField(
hintText: 'City',
validator: (String value) {
if (value.isEmpty) {
return 'Enter the city';
}
return null;
},
onSaved: (String value) {
schooldet.city = value;
},
),
MyTextFormField(
hintText: 'Pincode',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the pincode";
}
return null;
},
onSaved: (String value) {
schooldet.pincode = value;
},
),
MyTextFormField(
hintText: 'State',
isEmail: true,
validator: (String value) {
if (value.isEmpty) {
return "Enter the state";
}
return null;
},
onSaved: (String value) {
schooldet.state = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
widget.school.address = schooldet;
widget.onSaved(widget.school);
}
},
child:
Text('Next', style: TextStyle(color: Colors.white)))
]))));
}
}
form 3
class SchoolRegThree extends StatefulWidget {
School school;
final Function(School) onSaved;
SchoolRegThree({this.school, this.onSaved});
#override
_SchoolRegThreeState createState() => _SchoolRegThreeState();
}
class _SchoolRegThreeState extends State<SchoolRegThree> {
final _formKey = GlobalKey<FormState>();
SchoolUser schooluser;
#override
void initState() {
schooluser = widget.school.user;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: new Form(
key: _formKey,
child: Column(children: <Widget>[
Container(
margin: EdgeInsets.only(top: 100),
child: MyTextFormField(
hintText: 'Username',
isPassword: true,
validator: (String value) {
if (value.length < 5) {
return 'Username should be at least 5 characters long';
}
_formKey.currentState.save();
return null;
},
onSaved: (String value) {
schooluser.username = value;
},
),
),
MyTextFormField(
hintText: 'New Password',
isPassword: true,
validator: (String value) {
if (value.length < 7) {
return 'Password should be at least 7 characters long';
} else if (schooluser.password != null) {
print(value);
print(schooluser.password);
}
return null;
},
onSaved: (String value) {
schooluser.password = value;
},
),
RaisedButton(
color: Colors.blueAccent,
onPressed: () {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
widget.school.user = schooluser;
widget.onSaved(widget.school);
}
},
child: Text('Done',
style: TextStyle(
color: Colors.white,
)))
]))));
}
}
and finally consolidate the model to a single model class
class School {
String schoolName;
String schoolPhone;
String schoolEmail;
String schoolWebsite;
SchoolDet address;
SchoolUser user;
}
class SchoolDet {
String addressOne;
String addressTwo;
String city;
String pincode;
String state;
}
class SchoolUser {
String username;
String password;
}
Best is to use a state management solution like flutter_bloc, provider, etc.
Store it in an array on a different file using state management.
Make the bloc/provider available to all the screens.
You can pass through constructor but I don't recommend that as it will be too messy.