I have the below code and I want the country code and phone number side by side, how to get that? I have tried multiple examples, sometimes it disappears totally and sometimes crashes. I have the below code and I want the country code and phone number side by side, how to get that? I have tried multiple examples, sometimes it disappears totally and sometimes crashes.
import 'package:flutter/material.dart';
class Signup extends StatefulWidget{
Signup({Key key}) : super (key:key);
final String title;
#override
SignupPage createState() => new SignupPage();
}
class SignupPage extends State<Signup> {
List<String> _ccodes = <String>['', '+65', '+91', '+60', '+61'];
String _ccode = '';
#override
Widget build(BuildContext context) {
final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
onPressed: (){
print("Signup button clicked");
},
color: Colors.lightBlueAccent,
child:
Text('Sign Up',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
)
);
final countryCode = DropdownButton<String>(
value: _ccode,
isDense: true,
items: _ccodes.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_ccode = newValue;
});
}
)
;
final phonenumber = TextFormField(
keyboardType: TextInputType.phone,
autofocus: false,
initialValue: '91166666',
decoration: InputDecoration(
hintText: 'Phone Number',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
return Scaffold(
backgroundColor: Colors.white,
body: Center (
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
name,
SizedBox(height: 18.0),
email,
SizedBox(height: 18.0),
password,
SizedBox(height: 18.0),
passwordConfirmation,
SizedBox(height: 18.0),
Row(
children: [
new Expanded(
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
countryCode,
SizedBox(height: 18.0),
],
),
),
],
),
phonenumber,
SizedBox(height: 18.0),
loginButton,
SizedBox(height: 38.0),
],
)
)
);
}
}
Try checking this URL : https://flutter.io/tutorials/layout/
You can have different rows in your body to have adjacent components.
So the heirarchy would be like
Body
Container
Row{
Child: (item1)
Child(item2)}
Hope this helps. :)
The problem is related to way TextField gets rendered and their dimensions. You can find more details in this question and this issue.
Anyway this code should work:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new Signup(),
));
}
class Signup extends StatefulWidget {
Signup({Key key}) : super(key: key);
final String title;
#override
SignupPage createState() => new SignupPage();
}
class SignupPage extends State<Signup> {
List<String> _ccodes = <String>['', '+65', '+91', '+60', '+61'];
String _ccode = '';
#override
Widget build(BuildContext context) {
final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
onPressed: () {
print("Signup button clicked");
},
color: Colors.lightBlueAccent,
child: Text(
'Sign Up',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
));
final countryCode = DropdownButton<String>(
value: _ccode,
isDense: true,
items: _ccodes.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_ccode = newValue;
});
});
final phonenumber = TextFormField(
keyboardType: TextInputType.phone,
autofocus: false,
initialValue: '91166666',
decoration: InputDecoration(
hintText: 'Phone Number',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
name,
SizedBox(height: 18.0),
email,
SizedBox(height: 18.0),
password,
SizedBox(height: 18.0),
passwordConfirmation,
SizedBox(height: 18.0),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
countryCode,
new Flexible(child: phonenumber),
],
),
SizedBox(height: 18.0),
loginButton,
SizedBox(height: 38.0),
],
)));
}
}
Related
I am making an app in Flutter. Now I have put validator that to validate the email. But I want that if there is an google gmail account or any other valid email (actually has the user) then only the user should create account in app.
For example - Currently if I enter xyz#gmail.com then also the account is created on my app though this email doesn't exists as google account.
So my question is, Is there any way that app should validate first (If the email is valid account on gmail, outlook or any other but should be valid) and then account will create otherwise it should give error that Enter valid email???
I am using Firebase for Authentication.
My Code is below LoginPage.dart
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
String _email, _password, error = '';
bool _obscureText = true;
final Auth _auth = Auth();
_toggle(){
setState(() {
_obscureText = !_obscureText;
});
}
_submit() async {
if(_formKey.currentState.validate()){
_formKey.currentState.save();
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('email', _email);
dynamic result = await _auth.login(_email, _password);
if(result == null){
setState(() => error = 'There is no user record found. Please create account first!!!');
} else {
Navigator.pushNamed(context, HomePage.id);
}
print(_email);
print(_password);
}
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Login',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0, vertical: 10.0),
child: Padding(
padding: EdgeInsets.only(left: 5, right: 5, top: 5),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Email',
border: InputBorder.none,
filled: true,
fillColor: Colors.white60,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue,width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
/*enabledBorder: UnderlineInputBorder(
borderRadius: BorderRadius.circular(10.0)
)*/
),
validator: (input) => !input.contains('#')
? 'Please enter valid email'
: null,
onSaved: (input) => _email = input,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30.0, vertical: 10.0),
child: Stack(
alignment: const Alignment(0, 0),
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'Password',
border: InputBorder.none,
filled: true,
fillColor: Colors.white60,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue,width: 2.0),
borderRadius: BorderRadius.circular(10.0)
),
),
validator: (input) => input.length < 6
? 'Must be at least 6 characters'
: null,
onSaved: (input) => _password = input,
obscureText: _obscureText,
),
Positioned(
right: 15,
child: Container(
height: 30,
child: ElevatedButton(
onPressed: (){
_toggle();
},
child: Text(
_obscureText ? 'Show' : 'Hide'
),
),
),
),
],
),
),
verticalSpaceMedium,
Container(
width: 200.0,
child: TextButton(
onPressed: _submit,
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.blue,
elevation: 5,
),
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 16.0),
),
),
),
verticalSpaceMedium,
Container(
width: 200.0,
child: TextButton(
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors.blue,
elevation: 5,
),
onPressed: () => Navigator.pushNamed(context, SignupPage.id),
child: Text(
'Create Account',
),
),
),
verticalSpaceMedium,
Text(error, style: TextStyle(color: Colors.red, fontSize: 14),)
],
),
)
],
),
),
),
);
The above code works fine but want to add the validator that I have explained above.
See https://pub.dev/packages/email_validator. Do not attempt to write a regex to validate an email address. It will most certainly leave out some perfectly valid email forms that you might not have encountered yet. For example, both fred&barney#stonehenge.com (my autoresponder) and *#qz.to (an address a friend used for years, but now uses *#unspecified.example.com) are valid. Email Validator package correctly accepts both of those.
I want to add some text validation to my CupertinoTextField but there's no validator for this Widget. How can I solve this?
I tried searching on the internet for some solutions but nothing came out.
CupertinoTextField(
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
customIcon,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: maxLength,
maxLines: 1,
maxLengthEnforced: true,
placeholder: placeholderText,
onChanged: onChangedFunction,
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
)
You need to use TextEditingController & perform the validation manually.
Basic validation for checking if the field is empty or not.
code:
TextEditingController _myPhoneField = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_myPhoneField.text.isEmpty) {
showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text('error'),
content: Text('Phone Field is Empty'),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('ok'))
],
);
});
} else {
// Validation passed
}
},
child: Text('submit'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CupertinoTextField(
clearButtonMode: OverlayVisibilityMode.editing,
controller: _myPhoneField, // Add this
prefix: Padding(
padding: EdgeInsets.all(8.0),
child: Icon(
CupertinoIcons.phone_solid,
),
),
style: TextStyle(
fontSize: 30,
),
keyboardType: TextInputType.number,
maxLength: 10,
maxLines: 1,
maxLengthEnforced: true,
placeholder: 'Enter Phone',
onChanged: (v) {
print(v);
},
decoration: BoxDecoration(
border: Border.all(
width: 2.0,
color: CupertinoColors.inactiveGray,
),
borderRadius: BorderRadius.circular(32.0),
),
),
],
),
);
}
This is not about CupertinoTextField, but if you still want to validate input on Cupertino, you can use the CupertinoTextFormFieldRow widget.
CupertinoTextFormFieldRow(
controller: _usernameController,
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Please enter a valid username.';
}
return null;
},
decoration: BoxDecoration(
color: Colors.black12,
border: Border.all(
color: Colors.black12,
),
borderRadius: BorderRadius.circular(8.0),
),
)
I am very new to flutter and stuck on the point of displaying a SnackBar when login fails .Kindly check the code below and let me know how to fix this problem. I don't know where exactly do I need to have builder. You can suggest to me the best solution to display SnackBar in a simple and quick way. Many thanks in advance to all those who will help.
class LoginPage extends StatefulWidget {
static String tag = 'login-page';
#override
_LoginPageState createState() => new _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool passwordVisible = true;
var _scaffoldKey = new GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
final logo = Hero(
tag: 'hero',
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 48.0,
child: Image.asset('assets/splash.png'),
),
);
/* final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'mufeez#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
),
);
*/
final password = TextFormField(
autofocus: false,
obscureText: passwordVisible,//This will obscure text dynamically
decoration: InputDecoration(
hintText: 'Enter Secret Key',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(32.0)),
suffixIcon: IconButton(
icon: Icon(
// Based on passwordVisible state choose the icon
passwordVisible
? Icons.visibility_off
: Icons.visibility,
color: Theme.of(context).primaryColorDark,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
passwordVisible
? passwordVisible = false
: passwordVisible = true;
});
},
),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
onPressed: () async {
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
Scaffold.of(context).showSnackBar(snackBar);
},
padding: EdgeInsets.all(12),
color: Colors.lightBlueAccent,
child: Text('Log In', style: TextStyle(color: Colors.white)),
),
);
/* final forgotLabel = FlatButton(
child: Text(
'Forgot password?',
style: TextStyle(color: Colors.black54),
),
onPressed: () {},
);
*/
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: ListView(
shrinkWrap: true,
padding: EdgeInsets.only(left: 24.0, right: 24.0),
children: <Widget>[
logo,
SizedBox(height: 48.0),
SizedBox(height: 8.0),
password,
SizedBox(height: 24.0),
loginButton,
],
),
),
);
}
you have to use scaffold key to do so.
what you have to add in scaffold widget.
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
and at the time of display snackbar you have to use scaffold key.
replace your onPressed with below code.
onPressed: () async {
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
_scaffoldKey.currentState.showSnackBar(snackBar);
},
You can also wrap your Scaffold body in a Builder() widget.
return Scaffold(
body: body: Builder(
builder: (BuildContext ctxt) {
return (your content here);}));
and when want to display the Snackbar juste use Scaffold.of(ctxt) onPressed
onPressed: () {
Scaffold.of(ctxt).showSnackBar(
SnackBar(content:Text('My snack')));
},
I have form to grab info from User. But when I tap on TextFormField and keyboard shows it disappears.
https://youtu.be/UhVL2hqWOlQ
Here is my code:
class _AddInfoState extends State<AddInfo>{
static final GlobalKey<FormState> _key = new GlobalKey();
bool _validate = false;
String strTitle;
File fileImage;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body:new Container(
child: new Form(
key: _key,
autovalidate: _validate,
child: formUI(),
),
),
);
}
Widget formUI(){
return new ListView(
children: <Widget>[
//Title Field
new Container(
padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child:new TextFormField(
style: styleTextField,
keyboardType: TextInputType.text,
autofocus: true,
maxLength: 45,
decoration: InputDecoration(
hintText: 'Enter Title',
prefixIcon: Icon(
Icons.title,
size: 30.0,
color: blueColor,
)
),
validator: validateTitle,
onSaved: (String val) {
strTitle = val;
},
),
),
],
physics: new ClampingScrollPhysics(),
);
}
By my understanding from the video, since you have used a scrollable ListView inside your form, the list is scrolling upward once the keyboard appears hence it disappears.
Try setting resizeToAvoidBottomPadding: false in your Scaffold. This will make the keyboard appear as an overlay and won't push the content upward.
Example:
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
resizeToAvoidBottomPadding: false,
body:new Container(
child: new Form(
key: _key,
autovalidate: _validate,
child: formUI(),
),
),
);
}
Let me know if this helps!
Wrap the Container which has the TextFormField in a SizedBox :
new Form(
autovalidate: false,
key: _formKey,
child: new Container(
height: orientation == Orientation.portrait ? MediaQuery.of(context).size.height : MediaQuery.of(context).size.width/1.2 ,
padding: EdgeInsets.only(left: 10.0, right: 10.0),
child: new Column(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new SizedBox(
width: MediaQuery.of(context).size.width,
height: 100.0,
child: new Container(
padding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 0.0),
child:new TextFormField(
style: styleTextField,
keyboardType: TextInputType.text,
autofocus: true,
maxLength: 45,
decoration: InputDecoration(
hintText: 'Enter Title',
prefixIcon: Icon(
Icons.title,
size: 30.0,
color: blueColor,
)
),
validator: validateTitle,
onSaved: (String val) {
strTitle = val;
},
),
),
)
]
)
)
]
)
)
)
Set the resizeToAvoidBottomPadding: false and then change the Column to a ListView
I am trying to create a dropdown / combobox widget and having a hard time to figure. Below is the code that I have tried. Basically creating a list that I gathered from here and there but not able to put it in my own code accordingly.
import 'package:flutter/material.dart';
class Signup extends StatefulWidget{
Signup({Key key}) : super (key:key);
final String title;
#override
SignupPage createState() => new SignupPage();
}
class SignupPage extends State<Signup> {
#override
Widget build(BuildContext context) {
List _countrycodes = ["+65","+91"];
List<DropdownMenuItem<String>> _dropDownMenuItems;
String _selectedCountryCode;
List<String> _colors = <String>['', 'red', 'green', 'blue', 'orange'];
String _color = '';
List<DropdownMenuItem<String>> getDropDownMenuItems() {
List<DropdownMenuItem<String>> items = new List();
for (String code in _countrycodes) {
items.add(new DropdownMenuItem(
value: code,
child: new Text(code)
));
}
return items;
}
/**return new Material(
color: Colors.blueAccent,
child: new Scaffold(
body: new Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(image: new AssetImage("assets/images/download.jpg"), fit: BoxFit.cover,),
),
),
new Center(
child: new Text("Hello LandingPage"),
)
],
)
));**/
final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
onPressed: (){
print("Signup button clicked");
},
color: Colors.lightBlueAccent,
child:
Text('Sign Up',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
)
);
final countryCode = DropdownButton(
value: _selectedCountryCode,
items: _dropDownMenuItems,
onChanged: null
);
final inputDecoratoring =InputDecorator(
decoration: const InputDecoration(
icon: const Icon(Icons.color_lens),
labelText: 'Color',
),
isEmpty: _color == '',
child: new DropdownButtonHideUnderline(
child: new DropdownButton<String>(
value: _color,
isDense: true,
onChanged: (String newValue) {
setState(() {
_color = newValue;
});
},
items: _colors.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
),
),
);
return Scaffold(
backgroundColor: Colors.white,
body: Center (
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
name,
SizedBox(height: 18.0),
email,
SizedBox(height: 18.0),
password,
SizedBox(height: 18.0),
passwordConfirmation,
SizedBox(height: 18.0),
// countryCode,
// SizedBox(height: 18.0),
loginButton,
SizedBox(height: 38.0),
],
)
)
);
}
}
This is my main.dart class
import 'package:flutter/material.dart';
import 'package:elegal_dart/screens/landing_page.dart';
import 'package:elegal_dart/screens/home.dart';
import 'package:elegal_dart/screens/devices.dart';
import 'package:elegal_dart/screens/signup.dart';
import 'package:elegal_dart/screens/signin.dart';
/*
void main()
{
Devices( new MaterialApp(
home: new Devices(),
));
}*/
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget
{
#override
Widget build(BuildContext context)
{
return new MaterialApp(
title: 'Navigation',
routes: <String, WidgetBuilder>
{
'/Home' : (BuildContext context) => new Home(),
'/LandingPage' : (BuildContext context) => new LandingPage(),
'/Devices' : (BuildContext context) => new Devices(),
'/Signup' : (BuildContext context) => new Signup(),
'/Signin' : (BuildContext context) => new Signin(),
},
//home: new Signin(onSubmit: null),
home: new Signup(),
);
}
}
UPDATED CODE:
import 'package:flutter/material.dart';
class Signup extends StatefulWidget{
Signup({Key key}) : super (key:key);
final String title;
#override
SignupPage createState() => new SignupPage();
}
class SignupPage extends State<Signup> {
#override
Widget build(BuildContext context) {
List _countrycodes = ["+65","+91"];
List<DropdownMenuItem<String>> _dropDownMenuItems;
String _selectedCountryCode;
List<String> _ccodes = <String>['', '+65', '+91', '+60', 'orange'];
String _ccode = '';
List<DropdownMenuItem<String>> getDropDownMenuItems() {
List<DropdownMenuItem<String>> items = new List();
for (String code in _countrycodes) {
items.add(new DropdownMenuItem(
value: code,
child: new Text(code)
));
}
return items;
}
final name = TextFormField(
keyboardType: TextInputType.text,
autofocus: false,
initialValue: 'Techie Quickie',
decoration: InputDecoration(
hintText: 'Name',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final email = TextFormField(
keyboardType: TextInputType.emailAddress,
autofocus: false,
initialValue: 'tq#gmail.com',
decoration: InputDecoration(
hintText: 'Email',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final password = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final passwordConfirmation = TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
autofocus: false,
initialValue: 'password',
decoration: InputDecoration(
hintText: 'Password',
contentPadding: EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0)
),
),
);
final loginButton = Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
borderRadius: BorderRadius.circular(30.0),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 5.0,
child: MaterialButton(
minWidth: 200.0,
height: 42.0,
onPressed: (){
print("Signup button clicked");
},
color: Colors.lightBlueAccent,
child:
Text('Sign Up',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
)
);
final countryCode = DropdownButtonHideUnderline (
child: DropdownButton<String>(
value: _ccode,
isDense: true,
items: _ccodes.map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (String newValue) {
setState(() {
_ccode = newValue;
});
}
)
);
return Scaffold(
backgroundColor: Colors.white,
body: Center (
child: ListView(
padding: EdgeInsets.only(left: 24.0, right: 24.0),
shrinkWrap: true,
children: <Widget>[
name,
SizedBox(height: 18.0),
email,
SizedBox(height: 18.0),
password,
SizedBox(height: 18.0),
passwordConfirmation,
SizedBox(height: 18.0),
countryCode,
SizedBox(height: 18.0),
loginButton,
SizedBox(height: 38.0),
],
)
)
);
}
}
The error that I am getting in the AVD
The assertion tells you that items must not be null. It's referring to this one: items: _dropDownMenuItems,. You don't ever assign _dropDownMenuItems.
This is a good use for a Dart-y pattern. Replace it with:
final countryCode = DropdownButton(
value: _selectedCountryCode,
items: _countrycodes
.map((code) =>
new DropdownMenuItem(value: code, child: new Text(code)))
.toList(),
onChanged: null,
);
and you no longer need the field or the getDropDownMenuItems function. If you aren't familiar with this syntax, read it as "map each code in countryCodes to a DropdownMenuItem and form them back into a List"
Also, the scope of your variables is wrong. Move them out of the build function and into the State, like this:
class SignupPage extends State<Signup> {
List<String> _countrycodes = ["+65", "+91"];
List<String> _colors = ['', 'red', 'green', 'blue', 'orange'];
String _selectedCountryCode;
String _color = '';
My answer will solve also the problem of using more than one DropdownButton in the same page without the error of more than 1 item in the DropdownMenuItem .
First define the lists you will use this way:
static const List<String> _razas = const
["Schnauzer", "Ovejero Alemán", "Husky", "Brasov",
"Constanta","Mestizo"];
////////barrios
static const List<String> _barrios = const
"Belgrano", "Caballito", "Colegiales", "Lugano", "Palermo","Pilar",
"Montserrat", "Vicente López" ];
static const List<String> _tamanio = const
["Chico", "Mediano", "Grande" ];
String tamanioValue = _tamanio[0];
String barriosValue = _barrios[0];
String razasValue = _razas[0];
Then use this Containers in your Scaffold
Container(
margin: EdgeInsets.only(top:20.0, bottom: 20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children:<Widget> [
Text("RAZA "),
new DropdownButton(value:razasValue,
onChanged: (string) => setState(() => razasValue =
string),
items: _razas.map((string) {
return new DropdownMenuItem(
child: new Text(string),
value: string,
);
}).toList(),
),
]
)
),
Container(
margin: EdgeInsets.only(top:20.0, bottom: 20.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.start,
children:<Widget> [
Text("BARRIO "),
new DropdownButton(value:barriosValue,
onChanged: (string) => setState(() =>
barriosValue = string),
items: _barrios.map((string) {
return new DropdownMenuItem(
child: new Text(string),
value: string,
);
}).toList(),
),
]
)
),
Then just replace the values for you database or any file you store the data
raza: razasValue,
barrio: barriosValue,