Flutter: Unhandled Exception: Bad state: field does not exist within the DocumentSnapshotPlatform, not working - snapshot

I am new to flutter and i am building a Notes App. In my project i create three files main.dart, addUser.dart & editUser.dart My CREATE operation(addUser.dart) works properly & READ operation(main.dart) as well but when i click on read operation note it shows an red error with warning Bad state: field does not exist within the DocumentSnapshotPlatform
I am getting this error:
════════ Exception caught by widgets library ═══════════════════════════════════
The following StateError was thrown building Builder(dirty):
Bad state: field does not exist within the DocumentSnapshotPlatform
The relevant error-causing widget was
MaterialApp
lib\main.dart:18
When the exception was thrown, this was the stack
#0 DocumentSnapshotPlatform.get._findKeyValueInMap
package:cloud_firestore_platform_interface/…/platform_interface/
platform_interface_document_snapshot.dart:82
#1 DocumentSnapshotPlatform.get._findComponent
package:cloud_firestore_platform_interface/…/platform_interface/
platform_interface_document_snapshot.dart:98
#2 DocumentSnapshotPlatform.get
package:cloud_firestore_platform_interface/…/platform_interface/
platform_interface_document_snapshot.dart:113
#3 DocumentSnapshot.get
package:cloud_firestore/src/document_snapshot.dart:49
#4 DocumentSnapshot.[]
package:cloud_firestore/src/document_snapshot.dart:56
...
════════════════════════════════════════════════════════════════════════════════
Reloaded 2 of 826 libraries in 14,160ms.
Restarted application in 11,595ms.
W/DynamiteModule(10940): Local module descriptor class for providerinstaller not found.
I/DynamiteModule(10940): Considering local module providerinstaller:0 and remote module
providerinstaller:0
W/ProviderInstaller(10940): Failed to load providerinstaller module: No acceptable module found.
Local version is 0 and remote version is 0.
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 240 pixels on the bottom.
The relevant error-causing widget was
Column
lib\main.dart:96
To inspect this widget in Flutter DevTools, visit: http://127.0.0.1:9101/#/inspector?
uri=http%3A%2F%2F127.0.0.1%3A52941%2F0C0SU5iODJs%3D%2F&inspectorRef=inspector-0
The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen.
If the content is legitimately bigger than the available space, consider clipping it with a ClipRect
widget before putting it in the flex, or using a scrollable container rather than a Flex, like a
ListView.
The specific RenderFlex in question is: RenderFlex#b9fbf relayoutBoundary=up10 OVERFLOWING
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
A RenderFlex overflowed by 240 pixels on the bottom.
The relevant error-causing widget was
Column
lib\main.dart:96
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════
Bad state: field does not exist within the DocumentSnapshotPlatform
The relevant error-causing widget was
MaterialApp
lib\main.dart:18
════════════════════════════════════════════════════════════════════════════════
my Main.dart file
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:darwish_latest/addNote.dart';
import 'package:darwish_latest/editNote.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
CollectionReference ref = FirebaseFirestore.instance.collection('darwish');
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("UMHE Note"),
),
floatingActionButton: FloatingActionButton(
// backgroundColor: Colors.black,
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (_) => AddNote()));
}),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection("darwish")
.orderBy("time")
.snapshots(),
builder: (context, snapshot) {
return ListView.builder(
itemCount:
snapshot.hasData ? snapshot.data.documents.length : 0,
itemBuilder: (_, index) {
var darwish = snapshot.data.documents[index];
return snapshot.data.documents.length == 0
? Text("Text Notes Found")
: GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => EditNote(
darwish['empId'], darwish.id)));
},
child: Container(
margin: EdgeInsets.all(10),
constraints: BoxConstraints(maxHeight: 150),
color: Colors.grey.withOpacity(0.4),
child: Column(children: [
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['empid'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['user'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['email'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['password'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['DOB'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Text(darwish['address'],
style: GoogleFonts.sourceCodePro(
fontSize: 20)),
),
]),
),
);
});
},
));
}
}
my addNote.dart file
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
class AddNote extends StatefulWidget {
#override
_AddNoteState createState() => _AddNoteState();
}
class _AddNoteState extends State<AddNote> {
GlobalKey<FormState> formKey = GlobalKey<FormState>();
TextEditingController empId = TextEditingController();
TextEditingController user = TextEditingController();
TextEditingController emailid = TextEditingController();
TextEditingController passwordd = TextEditingController();
TextEditingController dobirth = TextEditingController();
TextEditingController myaddress = TextEditingController();
CollectionReference ref = FirebaseFirestore.instance.collection('darwish');
String empid = '';
String username = '';
String email = '';
String password = '';
String dob = '';
String address = '';
buildEmployeeid() => TextFormField(
controller: empId,
decoration: InputDecoration(
labelText: 'Employee Id',
border: OutlineInputBorder(),
),
validator: (value) {
if (value.isEmpty) {
return 'Employee id can not be empty';
}
return null;
},
onSaved: (value) => setState(() => empid = value),
);
Widget buildUsername() => TextFormField(
controller: user,
decoration: InputDecoration(
labelText: 'Username',
border: OutlineInputBorder(),
),
validator: (value) {
if (value.isEmpty) {
return 'Title can not be empty';
}
return null;
},
maxLength: 30,
onSaved: (value) => setState(() => username = value),
);
Widget buildEmail() => TextFormField(
controller: emailid,
decoration: InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
validator: (value) {
final pattern =
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+";
final regExp = RegExp(pattern);
if (value.isEmpty) {
return 'Email can not be empty';
} else if (!regExp.hasMatch(value)) {
return 'Enter a valid email';
}
return null;
},
keyboardType: TextInputType.emailAddress,
onSaved: (value) => setState(() => email = value),
);
Widget buildPassword() => TextFormField(
controller: passwordd,
decoration: InputDecoration(
labelText: 'Password',
border: OutlineInputBorder(),
),
validator: (value) {
if (value.isEmpty) {
return 'Password can not be empty';
}
return null;
},
onSaved: (value) => setState(() => password = value),
obscureText: true,
);
buildDOB() => TextFormField(
controller: dobirth,
decoration: InputDecoration(
labelText: 'Date Of Birth',
border: OutlineInputBorder(),
),
validator: (value) {
if (value.isEmpty) {
return 'Date of Birth can not be empty';
}
return null;
},
onSaved: (value) => setState(() => dob = value),
);
buildAddress() => TextFormField(
controller: myaddress,
decoration: InputDecoration(
labelText: 'Address',
border: OutlineInputBorder(),
),
validator: (value) {
if (value.isEmpty) {
return 'Address can not be empty';
}
return null;
},
maxLength: 30,
onSaved: (value) => setState(() => address = value),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
'UMHE Form',
),
),
body: Form(
key: formKey,
// autovalidate: true,
child: ListView(
padding: EdgeInsets.all(16),
children: [
buildEmployeeid(),
const SizedBox(height: 32),
buildUsername(),
const SizedBox(height: 16),
buildEmail(),
const SizedBox(height: 32),
buildPassword(),
const SizedBox(height: 32),
buildDOB(),
const SizedBox(height: 32),
buildAddress(),
const SizedBox(height: 32),
ElevatedButton(
child: Text(
'Submit',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
onPressed: () {
final isValid = formKey.currentState.validate();
FocusScope.of(context).unfocus();
if (isValid) {
// formKey.currentState.save();
ref.add({
'empid': empId.text,
'user': user.text,
'email': emailid.text,
'password': passwordd.text,
'DOB': dobirth.text,
'address': myaddress.text,
'time': DateTime.now()
});
formKey.currentState.reset();
return AlertDialog(
content: Text('Saved Successfully...'),
);
}
}),
],
),
),
);
}
}
my myEdit.dart file
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
class EditNote extends StatefulWidget {
String id;
String docid;
EditNote(id, docid);
#override
_EditNoteState createState() => _EditNoteState();
}
class _EditNoteState extends State<EditNote> {
GlobalKey<FormState> formKey = GlobalKey<FormState>();
TextEditingController empId = TextEditingController();
TextEditingController user = TextEditingController();
TextEditingController emailid = TextEditingController();
TextEditingController passwordd = TextEditingController();
TextEditingController dobirth = TextEditingController();
TextEditingController myaddress = TextEditingController();
#override
void initState() {
empId.text = widget.id;
}
CollectionReference ref = FirebaseFirestore.instance.collection("darwish");
editEmployeeId() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Employee Id can not be empty';
}
return null;
},
controller: empId,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'Employee Id',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
editUser() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'User can not be empty';
}
return null;
},
controller: user,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'User',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
editEmailId() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Email Id can not be empty';
}
return null;
},
controller: emailid,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'Email Id',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
editPassword() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Password can not be empty';
}
return null;
},
controller: passwordd,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'Password',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
editDOB() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'DOB can not be empty';
}
return null;
},
controller: dobirth,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'Date Of Birth',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
editMyAddress() => TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'Address can not be empty';
}
return null;
},
controller: myaddress,
decoration: InputDecoration(
// fillColor: Colors.grey.withOpacity(0.4),
filled: true,
hintText: 'Employee Id',
),
style: GoogleFonts.sourceCodePro(
fontSize: 25,
// color: Colors.black,
fontWeight: FontWeight.bold),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Edit Note"),
leading: IconButton(
icon: Icon(
Icons.arrow_back,
color: Colors.white,
),
onPressed: () => {Navigator.pop(context)}),
actions: [
IconButton(
icon: Icon(
Icons.delete,
color: Colors.white,
),
onPressed: () {
FirebaseFirestore.instance
.collection('darwish')
.doc(widget.docid)
.delete()
.then((value) => Navigator.pop(context));
}),
],
),
body: Form(
key: formKey,
child: ListView(
padding: EdgeInsets.all(16),
children: [
editEmployeeId(),
const SizedBox(height: 16),
editUser(),
const SizedBox(height: 32),
editEmailId(),
const SizedBox(height: 32),
editPassword(),
const SizedBox(height: 32),
editDOB(),
const SizedBox(height: 32),
editMyAddress(),
ElevatedButton(
child: Text(
'Update',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
onPressed: () {
if (formKey.currentState.validate()) {
FirebaseFirestore.instance
.collection("darwish")
.doc(widget.docid)
.set({
'empid': empId.text,
'user': user.text,
'email': emailid.text,
'password': passwordd.text,
'DOB': dobirth.text,
'address': myaddress.text,
// 'content': content.text,
'time': DateTime.now()
}).then((value) => Navigator.pop(context));
}
}),
],
)));
}
}

Related

The named parameter 'email is required, but there's no corresponding argument

I've a problem with this kind of bug and I hope someone can please tell me how to fix it.
The code:
import 'package:flutter/material.dart';
import 'package:login_form/model/login_model.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final scaffoldKey = GlobalKey<ScaffoldState>();
GlobalKey<FormState> globalFormKey = new GlobalKey<FormState>();
bool hidePassword = true;
LoginRequestModel requestModel;
#override
void initState() {
super.initState();
requestModel = new LoginRequestModel();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
backgroundColor: Theme.of(context).accentColor,
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 20),
margin: EdgeInsets.symmetric(vertical: 85, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Theme.of(context).primaryColor,
boxShadow: [
BoxShadow(
color: Theme.of(context).hintColor.withOpacity(0.2),
offset: Offset(0, 10),
blurRadius: 20)
],
),
child: Form(
key: globalFormKey,
child: Column(
children: <Widget>[
SizedBox(
height: 25,
),
Text(
"Login",
style: Theme.of(context).textTheme.headline2,
),
SizedBox(
height: 20,
),
new TextFormField(
keyboardType: TextInputType.emailAddress,
onSaved: (input) => requestModel.email = input,
validator: (input) =>
!(input?.contains("#") ?? false)
? "Email id Should be valid"
: null,
decoration: new InputDecoration(
hintText: "Email Address",
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentColor
.withOpacity(0.2),
)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor)),
prefixIcon: Icon(Icons.email,
color: Theme.of(context).accentColor),
),
),
SizedBox(
height: 20,
),
new TextFormField(
keyboardType: TextInputType.text,
onSaved: (input) => requestModel.password = input,
validator: (input) => (input != null &&
input.length < 3)
? "Password should be more than < 3 characters"
: null,
obscureText: hidePassword,
decoration: new InputDecoration(
hintText: "Password",
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentColor
.withOpacity(0.2),
)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor)),
prefixIcon: Icon(Icons.lock,
color: Theme.of(context).accentColor),
suffixIcon: IconButton(
onPressed: () {
setState(() {
hidePassword = !hidePassword;
});
},
icon: Icon(hidePassword
? Icons.visibility_off
: Icons.visibility),
),
),
),
SizedBox(
height: 30,
),
TextButton(
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (validateAndSave()) {
print(requestModel.toJson());
}
},
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(
vertical: 12,
horizontal: 80,
),
backgroundColor:
Theme.of(context).accentColor,
shape: StadiumBorder())),
],
),
),
),
],
)
],
),
));
}
bool validateAndSave() {
final form = globalFormKey.currentState;
if (form!.validate()) {
form.save();
return true;
}
return false;
}
}
this is my Loginmodel.dart code
class LoginResponseModel {
final String status;
final String message;
final String kid;
final String uid;
final String email;
final String password;
LoginResponseModel({
required this.status,
required this.message,
required this.kid,
required this.uid,
required this.email,
required this.password});
factory LoginResponseModel.fromJson(Map<String, dynamic> json) {
return LoginResponseModel(
status: json["status"] as String? ?? "",
message: json["message"] as String? ?? "",
kid: json["kid"] as String? ?? "",
uid: json["uid"] as String? ?? "",
email: json["email"] as String? ?? "",
password: json["password"] as String? ?? "",
);
}
}
class LoginRequestModel {
String email;
String password;
LoginRequestModel({
required this.email,
required this.password,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> map = {
'email': email.trim(),
'password': password.trim(),
};
return map;
}
}
The error:
The Error On LoginRequestModel requestModel; says " Non Nullable Instance field 'requestModel' must be initialized.
Then Error message on requestModel = new LoginRequestModel() says The Named Parameter 'email is required, but there's no corresponding argument.
And Last On OnSaved = input says "A value of type 'String?' can't be assigned to a variable of type 'string'."
I really appreciate the answer you gave
The Error On LoginRequestModel requestModel; says " Non Nullable Instance field 'requestModel' must be initialized.
You need to change:
LoginRequestModel requestModel;
Into the following since you are first setting the value in initState and therefore the variable are not going to be given a value right away then the object is created:
late LoginRequestModel requestModel;
Then Error message on requestModel = new LoginRequestModel() says The
Named Parameter 'email is required, but there's no corresponding
argument.
I don't know the content of the class LoginRequestModel but I would guess it has a named parameter email which is required to be specified when calling the LoginRequestModel constructor.
And Last On OnSaved = input says "A value of type 'String?' can't be assigned to a variable of type 'string'."
Again, I don't know your LoginRequestModel class but I would guess the email field is not nullable. That is a problem since onSave expects a method with the signature:
void FormFieldSetter<T>(
T? newValue
)
So your code here does not take into account that input is a nullable variable:
onSaved: (input) => requestModel.email = input
Since some of your problems is related to issues with Dart null-safety I will recommend you to read: https://dart.dev/null-safety
One by One,
The first one, you defined LoginRequestModel requestModel as non-nullable by default means that this variable is declared normally cannot be null. more detail You could just change LoginRequestModel requestModel; to LoginRequestModel requestModel= new LoginRequestModel();, instead of giving a value in initState. It looks like
LoginRequestModel requestModel = new LoginRequestModel();
#override
void initState() {
super.initState();
// requestModel = new LoginRequestModel();
}
Or use late (It is expensive)
Second one, I think in LoginRequestModel will lool like this LoginRequestModel({#required this.email}). You can choose to remove #required or give a empty value.
Last one, since requestModel.password and requestModel.email is non-nullable, it should like onSaved: (input) => requestModel.email = input!;
I think this should fix your problem.
In order to solve the error
assign the value of requestModel at the time of declaring it instead of in initState.
pass empty string as arguments to LoginRequestModel because email and password are required field.
write input! instead of input to indicate that input is not null
import 'package:flutter/material.dart';
import 'package:login_form/model/login_model.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final scaffoldKey = GlobalKey<ScaffoldState>();
GlobalKey<FormState> globalFormKey = new GlobalKey<FormState>();
bool hidePassword = true;
LoginRequestModel requestModel = new LoginRequestModel('','');
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
backgroundColor: Theme.of(context).accentColor,
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 20),
margin: EdgeInsets.symmetric(vertical: 85, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Theme.of(context).primaryColor,
boxShadow: [
BoxShadow(
color: Theme.of(context).hintColor.withOpacity(0.2),
offset: Offset(0, 10),
blurRadius: 20)
],
),
child: Form(
key: globalFormKey,
child: Column(
children: <Widget>[
SizedBox(
height: 25,
),
Text(
"Login",
style: Theme.of(context).textTheme.headline2,
),
SizedBox(
height: 20,
),
new TextFormField(
keyboardType: TextInputType.emailAddress,
onSaved: (input) => requestModel.email = input!,
validator: (input) =>
!(input?.contains("#") ?? false)
? "Email id Should be valid"
: null,
decoration: new InputDecoration(
hintText: "Email Address",
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentColor
.withOpacity(0.2),
)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor)),
prefixIcon: Icon(Icons.email,
color: Theme.of(context).accentColor),
),
),
SizedBox(
height: 20,
),
new TextFormField(
keyboardType: TextInputType.text,
onSaved: (input) => requestModel.password = input!,
validator: (input) => (input != null &&
input.length < 3)
? "Password should be more than < 3 characters"
: null,
obscureText: hidePassword,
decoration: new InputDecoration(
hintText: "Password",
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context)
.accentColor
.withOpacity(0.2),
)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).accentColor)),
prefixIcon: Icon(Icons.lock,
color: Theme.of(context).accentColor),
suffixIcon: IconButton(
onPressed: () {
setState(() {
hidePassword = !hidePassword;
});
},
icon: Icon(hidePassword
? Icons.visibility_off
: Icons.visibility),
),
),
),
SizedBox(
height: 30,
),
TextButton(
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (validateAndSave()) {
print(requestModel.toJson());
}
},
style: TextButton.styleFrom(
padding: EdgeInsets.symmetric(
vertical: 12,
horizontal: 80,
),
backgroundColor:
Theme.of(context).accentColor,
shape: StadiumBorder())),
],
),
),
),
],
)
],
),
));
}
bool validateAndSave() {
final form = globalFormKey.currentState;
if (form!.validate()) {
form.save();
return true;
}
return false;
}
}

is there a way to merge dynamically loaded image file to one image file in flutter?

Is there a way to merge dynamically loaded image file to one image file in flutter?
I have added the image.
I needed to merge the loaded image to one image the code I have used is given below
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image/image.dart' as immg;
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:merge_images/merge_images.dart';
class SingleImageUpload extends StatefulWidget {
#override
_SingleImageUploadState createState() {
return _SingleImageUploadState();
}
}
class _SingleImageUploadState extends State<SingleImageUpload> {
List<Object> images = List<Object>();
List<File> imgList = List<File>();
List<Image> listimg = List<Image>();
File _selectedFile;
bool _inProcess = false;
Map data = {};
Readerservice _readerservice;
#override
void initState() {
// TODO: implement initState
super.initState();
setState(() {
images.add("Add Image");
images.add("Add Image");
images.add("Add Image");
images.add("Add Image");
});
}
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
home: new Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: Padding(
padding: EdgeInsets.only(left: 12),
child: IconButton(
icon: Icon(Icons.arrow_back_ios,
color: Colors.black,
size: 30,),
onPressed: () {
Navigator.pushNamed(context, '/Mainpage');
},
),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:<Widget>[
Text('Basic AppBar'),
]
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.more_vert,
color: Colors.black,
size: 30,),
onPressed: () {
print('Click start');
},
),
],
),
body:
SizedBox(height: 40),
Expanded(
child: buildGridView(),
),
RaisedButton(
textColor: Colors.white,
color: Colors.orange,
child: Text("Finish",
style: TextStyle(fontSize: 15),),
onPressed: () {
pasimage();
},
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(8.0),
),
),
],
),
),
);
}
Widget buildGridView() {
return GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
childAspectRatio: 1,
children: List.generate(images.length, (index) {
if (images[index] is ImageUploadModel) {
ImageUploadModel uploadModel = images[index];
return Card(
clipBehavior: Clip.antiAlias,
child: Stack(
children: <Widget>[
Image.file(
uploadModel.imageFile,
width: 300,
height: 300,
),
Positioned(
right: 5,
top: 5,
child: InkWell(
child: Icon(
Icons.remove_circle,
size: 20,
color: Colors.red,
),
onTap: () {
setState(() {
images.replaceRange(index, index + 1, ['Add Image']);
});
},
),
),
],
),
);
} else {
return Card(
child: IconButton(
icon: Icon(Icons.add),
onPressed: () {
//popup
showDialog(
context: context,
builder: (context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
elevation: 16,
child: Container(
height: 180.0,
width: 330.0,
child: ListView(
children: <Widget>[
SizedBox(height: 20),
//Center(
Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Text(
"Add a Receipt",
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 24,
color: Colors.black,
fontWeight: FontWeight.bold),
),
),
// ),
SizedBox(height: 20),
FlatButton(
child: Text(
'Take a photo..',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 20),
),
onPressed: () {
_onAddImageClick(index,ImageSource.camera);
Navigator.of(context).pop();
// picker.getImage(ImageSource.camera);
},
textColor: Colors.black,
),
FlatButton(
child: Text(
'Choose from Library..',
style: TextStyle(fontSize: 20),
textAlign: TextAlign.left,
),
onPressed: () {
_onAddImageClick(index,ImageSource.gallery);
Navigator.of(context).pop();
},
textColor: Colors.black,
),
],
),
),
);
},
);
//pop ends
//_onAddImageClick(index);
},
),
);
}
}),
);
}
Future _onAddImageClick(int index, ImageSource source ) async {
setState(() {
_inProcess = true;
});
File image = await ImagePicker.pickImage(source: source);
if(image != null){
File cropped = await ImageCropper.cropImage(
sourcePath: image.path,
maxWidth: 1080,
maxHeight: 1080,
compressFormat: ImageCompressFormat.jpg,
androidUiSettings: AndroidUiSettings(
toolbarColor: Colors.black,
toolbarWidgetColor: Colors.white,
//toolbarTitle: "RPS Cropper",
statusBarColor: Colors.deepOrange.shade900,
backgroundColor: Colors.black,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false
),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
)
);
this.setState((){
_selectedFile = cropped ;
_inProcess = false;
});
} else {
this.setState((){
_inProcess = false;
});
}
getFileImage(index);
}
void getFileImage(int index) async {
// var dir = await path_provider.getTemporaryDirectory();
setState(() {
ImageUploadModel imageUpload = new ImageUploadModel();
imageUpload.isUploaded = false;
imageUpload.uploading = false;
imageUpload.imageFile = _selectedFile ;
imageUpload.imageUrl = '';
imgList.add(imageUpload.imageFile);
images.replaceRange(index, index + 1, [imageUpload]);
print(imgList);
});
}
void pasimage(){
for(var i=0;i<imgList.length;i++){
final imaes = immg.decodeImage(imgList[i].readAsBytesSync()) as Image;
listimg.add(imaes);
}
Navigator.pushReplacementNamed(context, '/crop',arguments: {
'imageList':ImagesMerge(
listimg,///required,images list
direction: Axis.vertical,///direction
backgroundColor: Colors.black26,///background color
fit: false,///scale image to fit others
//controller: captureController,///controller to get screen shot
),
});
}
}
class ImageUploadModel {
bool isUploaded;
bool uploading;
File imageFile;
String imageUrl;
ImageUploadModel({
this.isUploaded,
this.uploading,
this.imageFile,
this.imageUrl,
});
}
I have used image merge package from pub.dev I have implemented it in pasimage() function but I got the error.
** The argument type 'List (where Image is defined in C:\src\flutter\packages\flutter\lib\src\widgets\image.dart)' can't be assigned to the parameter type 'List (where Image is defined in C:\src\flutter\bin\cache\pkg\sky_engine\lib\ui\painting.dart)'. **
the error image is attached
import 'dart:ui' as ui;
List<ui.Image> listimg = List<ui.Image>();
...
void pasimage(){
for(var i=0;i<imgList.length;i++){
final imaes = await ImagesMergeHelper.loadImageFromFile(imgList[i]) as ui.Image;
listimg.add(imaes);
}
Navigator.pushReplacementNamed(context, '/crop',arguments: {
'imageList':ImagesMerge(
listimg,///required,images list
direction: Axis.vertical,///direction
backgroundColor: Colors.black26,///background color
fit: false,///scale image to fit others
//controller: captureController,///controller to get screen shot
),
});
}
Try this code.

Why isn't the image changing using the Provider Package?

I'm working with the Provider Package on Flutter but can't work out why it's not changing the background image when I call mymodel.image. It should access the MyModal class and change the existing image: Image.asset('images/background_image.jpeg', fit: BoxFit.fill) with the one in the SmallImage screen.
mymodel.image = Image.asset('images/hello_image.png', fit: BoxFit.fill);
Which replaces the background image on the HomePage.
HomePage Screen
import 'package:flutter/material.dart';
import 'package:flutter_app_background/small_images.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider<MyModel>(
create: (context) => MyModel(),
child: MaterialApp(
title: 'Title',
home: HomePage(),
),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
title: Text('Background Image', style: TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.settings, color: Colors.black,),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SmallImages()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Stack(
children: <Widget>
[
Positioned.fill(
child: GestureDetector(
child: Consumer<MyModel>(
builder: (context, myModel, child) {
return myModel.image = Image.asset('images/background_image.jpeg', fit: BoxFit.fill);
},
),
),
),
],
),
);
}
}
class MyModel extends ChangeNotifier {
Image _image;
set image(Image value) {
_image = value;
notifyListeners();
}
Image get image => _image;
}
SmallImage Screen
import 'package:flutter/material.dart';
import 'package:flutter_app_background/main.dart';
import 'package:provider/provider.dart';
class SmallImages extends StatefulWidget {
static int tappedGestureDetector = 1;
#override
_SmallImagesState createState() => _SmallImagesState();
}
class _SmallImagesState extends State<SmallImages> {
List<bool> isSelected;
void initState() {
isSelected = [true, false, false, false, false, false, false, false, false];
super.initState();
}
#override
Widget build(BuildContext context) {
final mymodel = Provider.of<MyModel>(context,listen:false); //default for listen is `true`
return Scaffold(
appBar: AppBar(
title: Text('Small Image', style: TextStyle(
color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.arrow_left, color: Colors.black,),
onPressed: () {
Navigator.pop(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
},
),
],
backgroundColor: Colors.transparent,
elevation: 0.0,
),
body: Material(
child: GestureDetector(
child: MaterialApp(
builder: (context, snapshot) {
return GridView.count(
crossAxisCount: 1,
childAspectRatio: 1.0,
padding: const EdgeInsets.all(4.0),
mainAxisSpacing: 0.0,
crossAxisSpacing: 0.0,
children: [
GridView(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3,
childAspectRatio: MediaQuery
.of(context)
.size
.width /
(MediaQuery
.of(context)
.size
.height / 2),
),
children: [
GestureDetector(
onTap: () {
// return myValue;
setState(() {
SmallImages.tappedGestureDetector = 1;
});
return mymodel.image = Image.asset('images/hello_image.png', fit: BoxFit.fill);
print('hi');
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 1
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/nightsky_image.png',
),
),
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 2;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 2
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/own_image.png',
),
),
);
},
),
Consumer<MyModel>(
builder: (context, myModel, child) {
return GestureDetector(
onTap: () {
setState(() {
SmallImages.tappedGestureDetector = 3;
}); // <-- replaced 'tapped' and 'other'
},
child: Container(
height: 100,
width: 107,
decoration: BoxDecoration(border: SmallImages
.tappedGestureDetector == 3
? Border.all(
color: Color(0xff2244C7), width: 1.0)
: Border
.all(color: Colors.transparent,),),
child: Image.asset(
'images/iceland_image.png',
),
),
);
},
),
].toList(),
),
],
);
}),
),
),
);
}
}
You have to call notifyListeners in your model when the image has changed otherwise the changenotifierprovider will not know that it needs to rebuild.
One way of doing the would be to wrap the image field with a getter and setter and call notifyListeners in the setter after updating the underlying field.
var Image _image;
set image(Image value) {
_image = value;
notifyListeners();
}
Image get image => _image;

Flutter Radio Buttons validation

I am implementing a custom radio button with validation and values are passed in those buttons. There is a run time error which i am not able to figure out. I am getting the following error
The following assertion was thrown during performLayout():
I/flutter (10799): An InputDecorator, which is typically created by a TextField, cannot have an unbounded width.
I/flutter (10799): This happens when the parent widget does not provide a finite width constraint. For example, if the
I/flutter (10799): InputDecorator is contained by a Row, then its width must be constrained. An Expanded widget or a
I/flutter (10799): SizedBox can be used to constrain the width of the InputDecorator or the TextField that contains it.
I/flutter (10799): 'package:flutter/src/material/input_decorator.dart':
I/flutter (10799): Failed assertion: line 945 pos 7: 'layoutConstraints.maxWidth < double.infinity'
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter FormBuilder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
inputDecorationTheme: InputDecorationTheme(
labelStyle: TextStyle(color: Colors.purple),
),
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
MyHomePageState createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
var data;
bool autoValidate = true;
bool readOnly = false;
bool showSegmentedControl = true;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
final GlobalKey<FormFieldState> _specifyTextFieldKey =
GlobalKey<FormFieldState>();
ValueChanged _onChanged = (val) => print(val);
// var genderOptions = ['Male', 'Female', 'Other'];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("FormBuilder Example"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
child: Row(
children: <Widget>[
FormBuilder(
// context,
key: _fbKey,
autovalidate: true,
//initialValue: {
// 'movie_rating': 5,
// },
readOnly: false,
child: Row(
children: <Widget>[
FormBuilderRadio(
decoration:
InputDecoration(labelText: 'My chosen language'),
attribute: "best_language",
leadingInput: true,
onChanged: _onChanged,
validators: [FormBuilderValidators.required()],
options:
["Delete", "Approve", "Revert"]
.map((lang) => FormBuilderFieldOption(
value: lang,
child: Text('$lang'),
))
.toList(growable: false),
),
],
),
),
Row(
children: <Widget>[
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Submit",
style: TextStyle(color: Colors.white),
),
onPressed: () {
if (_fbKey.currentState.saveAndValidate()) {
print(_fbKey.currentState.value);
} else {
print(_fbKey.currentState.value);
print("validation failed");
}
},
),
),
SizedBox(
width: 20,
),
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Reset",
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.reset();
},
),
),
],
),
],
),
),
),
);
}
}
void changeIndex() {
setState(() {
selectedIndex = 1;
print("Value passed is delete");
});
}
void changeIndex1() {
setState(() {
selectedIndex = 1;
print("Value passed is a");
});
}
void changeIndex2() {
setState(() {
selectedIndex = 1;
print("Value passed is r");
});
}
Widget customRadio1() => OutlineButton(
onPressed: () => changeIndex(),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
borderSide: BorderSide(
color: selectedIndex == 0 ? Colors.red : Colors.grey),
child: Text(lst[0], style: TextStyle(
color: selectedIndex == 0 ? Colors.red : Colors.grey),),
);
Widget customRadio2() => OutlineButton(
onPressed: () => changeIndex1(),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
borderSide: BorderSide(
color: selectedIndex == 1 ? Colors.green : Colors.grey),
child: Text(lst[1], style: TextStyle(
color: selectedIndex == 1 ? Colors.green : Colors.grey),),
);
Widget customRadio3() {
return OutlineButton(
onPressed: () => changeIndex2(),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
borderSide: BorderSide(
color: selectedIndex == 2 ? Colors.cyan : Colors.grey),
child: Text(lst[2], style: TextStyle(
color: selectedIndex == 2 ? Colors.cyan : Colors.grey),),
);
}
}
An InputDecorator cannot have an unbounded width as mentioned in the logs. The cause of this is that the InputDecorator is in a Scrollable Row and has an undefined width. To solve this issue, you can wrap the child widgets in the Row with a Container with a width configured.

How to validate drop down in flutter

I've created on the dropdown and i want to validate that dropdown. when a user doesn't select an item from drop-down then it will show a validation.
here is some code I've tried so far.
in this code I've created one drop down when I am click submit then it will show a validation when the user doesn't select an item from the dropdown.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dropdown Validation',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> _type = <String>[
'Passport',
'Driving License',
'Voter ID card',
'Ration Card',
'Aadhar',
'Other Id'
];
String type = 'Local Goverment';
Widget _buildlicenseissuingauthority() {
return FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
prefixIcon: Icon(Icons.location_on),
labelText: 'Select Personal Identification type',
),
isEmpty: type == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
value: type,
isDense: true,
onChanged: (String newValue) {
setState(() {
type = newValue;
});
},
items: _type.map(
(String value) {
return new DropdownMenuItem(
value: value,
child: new Text(value),
);
},
).toList(),
),
),
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[_buildlicenseissuingauthority()],
),
),
);
}
}
please use pacakge https://pub.dev/packages/flutter_form_builder
github https://github.com/danvick/flutter_form_builder
It has more than 10 buildin validators, in your case FormBuilderValidators.required()
code snippet
FormBuilderDropdown(
attribute: "gender",
decoration: InputDecoration(
labelText: "Gender",
icon: const Icon(Icons.category),
hintText: "Select hint",
),
// initialValue: 'Male',
onChanged: _onChanged,
hint: Text('Select Gender'),
validators: [FormBuilderValidators.required()],
items: ['Male', 'Female', 'Other']
.map((gender) => DropdownMenuItem(
value: gender,
child: Text('$gender'),
))
.toList(),
)
full example code
import 'package:datetime_picker_formfield/datetime_picker_formfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:intl/intl.dart';
import './data.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter FormBuilder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
MyHomePageState createState() {
return MyHomePageState();
}
}
class MyHomePageState extends State<MyHomePage> {
var data;
bool autoValidate = true;
bool readOnly = false;
bool showSegmentedControl = true;
final GlobalKey<FormBuilderState> _fbKey = GlobalKey<FormBuilderState>();
final GlobalKey<FormFieldState> _specifyTextFieldKey =
GlobalKey<FormFieldState>();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
ValueChanged _onChanged = (val) => print(val);
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("FormBuilder Example"),
),
body: Padding(
padding: EdgeInsets.all(10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
FormBuilder(
// context,
key: _fbKey,
autovalidate: true,
// readonly: true,
child: Column(
children: <Widget>[
FormBuilderCustomField(
attribute: "name",
validators: [
FormBuilderValidators.required(),
],
formField: FormField(
// key: _fieldKey,
enabled: true,
builder: (FormFieldState<dynamic> field) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.laptop),
hintText: "Select hint",
labelText: "Select option",
contentPadding:
EdgeInsets.only(top: 10.0, bottom: 0.0),
border: InputBorder.none,
errorText: field.errorText,
),
child: DropdownButton(
isExpanded: true,
items: ["One", "Two"].map((option) {
return DropdownMenuItem(
child: Text("$option"),
value: option,
);
}).toList(),
value: field.value,
onChanged: (value) {
field.didChange(value);
},
),
);
},
),
),
FormBuilderChipsInput(
decoration: InputDecoration(
labelText: "Chips",
icon: const Icon(Icons.person),
hintText: "Select hint",
),
attribute: 'chips_test',
// readonly: true,
onChanged: _onChanged,
// valueTransformer: (val) => val.length > 0 ? val[0] : null,
initialValue: [
Contact('Andrew', 'stock#man.com',
'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
],
maxChips: 5,
findSuggestions: (String query) {
if (query.length != 0) {
var lowercaseQuery = query.toLowerCase();
return mockResults.where((profile) {
return profile.name
.toLowerCase()
.contains(query.toLowerCase()) ||
profile.email
.toLowerCase()
.contains(query.toLowerCase());
}).toList(growable: false)
..sort((a, b) => a.name
.toLowerCase()
.indexOf(lowercaseQuery)
.compareTo(b.name
.toLowerCase()
.indexOf(lowercaseQuery)));
} else {
return const <Contact>[];
}
},
chipBuilder: (context, state, profile) {
return InputChip(
key: ObjectKey(profile),
label: Text(profile.name),
avatar: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
onDeleted: () => state.deleteChip(profile),
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
);
},
suggestionBuilder: (context, state, profile) {
return ListTile(
key: ObjectKey(profile),
leading: CircleAvatar(
backgroundImage: NetworkImage(profile.imageUrl),
),
title: Text(profile.name),
subtitle: Text(profile.email),
onTap: () => state.selectSuggestion(profile),
);
},
),
FormBuilderDateTimePicker(
attribute: "date",
onChanged: _onChanged,
inputType: InputType.date,
format: DateFormat("yyyy-MM-dd"),
decoration: InputDecoration(
labelText: "Appointment Time",
icon: const Icon(Icons.calendar_today),
hintText: "Select hint",
),
// readonly: true,
),
FormBuilderSlider(
attribute: "slider",
validators: [FormBuilderValidators.min(6)],
onChanged: _onChanged,
min: 0.0,
max: 10.0,
initialValue: 1.0,
divisions: 20,
decoration: InputDecoration(
labelText: "Number of somethings",
icon: const Icon(Icons.snooze),
hintText: "Select hint",
),
),
FormBuilderCheckbox(
decoration: InputDecoration(
labelText: "terms",
icon: const Icon(Icons.subject),
hintText: "Select hint",
),
attribute: 'accept_terms',
initialValue: false,
onChanged: _onChanged,
leadingInput: true,
label: Text(
"I have read and agree to the terms and conditions"),
validators: [
FormBuilderValidators.requiredTrue(
errorText:
"You must accept terms and conditions to continue",
),
],
),
FormBuilderDropdown(
attribute: "gender",
decoration: InputDecoration(
labelText: "Gender",
icon: const Icon(Icons.category),
hintText: "Select hint",
),
// initialValue: 'Male',
onChanged: _onChanged,
hint: Text('Select Gender'),
validators: [FormBuilderValidators.required()],
items: ['Male', 'Female', 'Other']
.map((gender) => DropdownMenuItem(
value: gender,
child: Text('$gender'),
))
.toList(),
),
FormBuilderTextField(
attribute: "age",
decoration: InputDecoration(
labelText: "Age",
icon: const Icon(Icons.accessibility),
hintText: "Select hint",
),
onChanged: _onChanged,
valueTransformer: (text) => num.tryParse(text),
validators: [
FormBuilderValidators.numeric(),
FormBuilderValidators.max(70),
],
),
FormBuilderTypeAhead(
// initialValue: "Canada",
decoration: InputDecoration(
labelText: "Country",
icon: const Icon(Icons.golf_course),
hintText: "Select hint",
),
attribute: 'country',
onChanged: _onChanged,
itemBuilder: (context, country) {
return ListTile(
title: Text(country),
);
},
suggestionsCallback: (query) {
if (query.length != 0) {
var lowercaseQuery = query.toLowerCase();
return allCountries.where((country) {
return country
.toLowerCase()
.contains(lowercaseQuery);
}).toList(growable: false)
..sort((a, b) => a
.toLowerCase()
.indexOf(lowercaseQuery)
.compareTo(
b.toLowerCase().indexOf(lowercaseQuery)));
} else {
return allCountries;
}
},
),
FormBuilderRadio(
decoration: InputDecoration(
labelText: 'My chosen language',
icon: const Icon(Icons.language),
hintText: "Select hint",
),
attribute: "best_language",
leadingInput: true,
onChanged: _onChanged,
validators: [FormBuilderValidators.required()],
options: [
"Dart",
"Kotlin",
"Java",
"Swift",
"Objective-C"
]
.map((lang) => FormBuilderFieldOption(value: lang))
.toList(growable: false),
),
FormBuilderSegmentedControl(
decoration: InputDecoration(
labelText: "Movie Rating (Archer)",
icon: const Icon(Icons.crop_rotate),
hintText: "Select hint",
),
attribute: "movie_rating",
options: List.generate(5, (i) => i + 1)
.map(
(number) => FormBuilderFieldOption(value: number))
.toList(),
onChanged: _onChanged,
),
FormBuilderSwitch(
decoration: InputDecoration(
labelText: "conditions",
icon: const Icon(Icons.dashboard),
hintText: "Select hint",
),
label: Text('I Accept the tems and conditions'),
attribute: "accept_terms_switch",
initialValue: true,
onChanged: _onChanged,
),
FormBuilderStepper(
decoration: InputDecoration(
labelText: "Stepper",
icon: const Icon(Icons.account_box),
hintText: "Select hint",
),
attribute: "stepper",
initialValue: 10,
step: 1,
validators: [
(val) {
if (!_fbKey.currentState.fields["accept_terms_switch"]
.currentState.value &&
val >= 10) {
return "You can only put more than 10 if you've accepted terms";
}
}
],
),
FormBuilderRate(
decoration: InputDecoration(
labelText: "Rate this form",
icon: const Icon(Icons.branding_watermark),
hintText: "Select hint",
),
attribute: "rate",
iconSize: 32.0,
initialValue: 1,
max: 5,
onChanged: _onChanged,
),
FormBuilderCheckboxList(
decoration: InputDecoration(
labelText: "The language of my people",
icon: const Icon(Icons.collections),
hintText: "Select hint",
),
attribute: "languages",
initialValue: ["Dart"],
leadingInput: true,
options: [
FormBuilderFieldOption(value: "Dart"),
FormBuilderFieldOption(value: "Kotlin"),
FormBuilderFieldOption(value: "Java"),
FormBuilderFieldOption(value: "Swift"),
FormBuilderFieldOption(value: "Objective-C"),
],
onChanged: _onChanged,
),
FormBuilderCustomField(
attribute: 'custom',
valueTransformer: (val) {
if (val == "Other")
return _specifyTextFieldKey.currentState.value;
return val;
},
formField: FormField(
builder: (FormFieldState<String> field) {
var languages = [
"English",
"Spanish",
"Somali",
"Other"
];
return InputDecorator(
decoration: InputDecoration(
labelText: "What's your preferred language?",
icon: const Icon(Icons.bug_report),
hintText: "Select hint",
),
child: Column(
children: languages
.map(
(lang) => Row(
children: <Widget>[
Radio<dynamic>(
value: lang,
groupValue: field.value,
onChanged: (dynamic value) {
field.didChange(lang);
},
),
lang != "Other"
? Text(lang)
: Expanded(
child: Row(
children: <Widget>[
Text(
lang,
),
SizedBox(width: 20),
Expanded(
child: TextFormField(
key:
_specifyTextFieldKey,
),
),
],
),
),
],
),
)
.toList(growable: false),
),
);
},
),
),
FormBuilderSignaturePad(
decoration: InputDecoration(
labelText: "Signature",
icon: const Icon(Icons.card_travel),
hintText: "Select hint",
),
attribute: "signature",
// height: 250,
clearButtonText: "Start Over",
onChanged: _onChanged,
),
],
),
),
Row(
children: <Widget>[
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Submit",
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.save();
if (_fbKey.currentState.validate()) {
print(_fbKey.currentState.value);
} else {
print(_fbKey.currentState.value);
print("validation failed");
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text('Validation failed'),
duration: Duration(seconds: 3),
));
}
},
),
),
SizedBox(
width: 20,
),
Expanded(
child: MaterialButton(
color: Theme.of(context).accentColor,
child: Text(
"Reset",
style: TextStyle(color: Colors.white),
),
onPressed: () {
_fbKey.currentState.reset();
},
),
),
],
),
],
),
),
),
);
}
}
Data.dart
class Contact {
final String name;
final String email;
final String imageUrl;
const Contact(this.name, this.email, this.imageUrl);
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is Contact &&
runtimeType == other.runtimeType &&
name == other.name;
#override
int get hashCode => name.hashCode;
#override
String toString() {
return name;
}
}
const allCountries = [
"Afghanistan",
"Albania",
"Algeria",
"American Samoa",
"Andorra",
"Angola",
"Anguilla",
];
const contacts = <Contact>[
Contact('Andrew', 'stock#man.com',
'https://d2gg9evh47fn9z.cloudfront.net/800px_COLOURBOX4057996.jpg'),
Contact('Paul', 'paul#google.com',
'https://mbtskoudsalg.com/images/person-stock-image-png.png'),
Contact('Fred', 'fred#google.com',
'https://media.istockphoto.com/photos/feeling-great-about-my-corporate-choices-picture-id507296326'),
Contact('Brian', 'brian#flutter.io',
'https://upload.wikimedia.org/wikipedia/commons/7/7c/Profile_avatar_placeholder_large.png'),
];
demo, after click submit button, you can see gender has red text "This field can not be empty"
Flutter already has its own Form DropDownButtom for this
List<String> typeNeg = [
"One",
"Two",
"Three",];
String dropdownValue = "One";
DropdownButtonFormField<String>(
value: dropdownValue,
hint: Text("Type of business"),
onChanged: (String newValue) {
setState(() {
dropdownValue = newValue;
});
},
validator: (String value) {
if (value?.isEmpty ?? true) {
return 'Please enter a valid type of business';
}
},
items: typeNeg
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onSaved: (val) => setState(() => _user.typeNeg = val),
),

Resources