Related
Ok so I've spent the last 3 days watching singlechildscroll videos and reading forums and everyone says use singlechildscroll. For the life of me I can not get this widget to work with my signup page. I've placed this widget at almost every level and wrapping it in expanded and outside expanded amongst other widgets like containers or paddings with special viewinset.bottom settings and its just been a nightmare the amount of variances I've tried and still cant figure this out so I'm reaching out cause I'm out of ideas now.
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:vext/controllers/auth_controller.dart';
import 'package:vext/helpers/constants.dart';
import 'package:vext/screens/login_screen.dart';
import 'package:vext/widgets/decorativeWidgets/rounded_text_form_field.dart';
import 'package:vext/widgets/decorativeWidgets/vext_elevated_button.dart';
import 'login_title.dart';
class SignUp extends StatefulWidget {
const SignUp({Key? key}) : super(key: key);
#override
State<SignUp> createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final _signUpFormKey = GlobalKey<FormState>();
final TextEditingController _nameController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
final _authController = Get.find<AuthController>();
final FocusNode _nameFocus = FocusNode();
final FocusNode _emailFocus = FocusNode();
final FocusNode _passwordFocus = FocusNode();
final FocusNode _passwordConfirmFocus = FocusNode();
bool _isLoading = false;
#override
void dispose() {
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_authController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
bool keyboardIsOpen = MediaQuery.of(context).viewInsets.bottom != 0;
debugPrint('New user Sign Up Initiated');
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: kPrimaryColor,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 40.h,
),
LoginTitle(
title: 'Sign Up',
subtitle: 'Create an account...',
titleFontSize: 75.sp,
subFontSize: 25.sp,
),
SizedBox(height: 15.h),
buildSignUpForm(),
SizedBox(height: 30.h),
Text(
'Already have an account?',
style: TextStyle(
fontSize: 20.sp,
),
),
TextButton(
onPressed: () {
FocusScope.of(context).unfocus();
Get.to(() => LoginScreen());
},
child: Text(
'Sign In',
style: TextStyle(
color: kSecondaryColor,
fontSize: 20.sp,
),
),
style: ButtonStyle(
overlayColor: MaterialStateColor.resolveWith((states) => Colors.transparent),
),
),
// Padding(
// padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
// ),
],
),
),
);
}
// Sign-up form Section
Form buildSignUpForm() {
return Form(
key: _signUpFormKey,
child: Column(
children: <Widget>[
RoundedTextFormField(
autoFocus: true,
focusNode: _nameFocus,
onFieldSubmitted: (term) {
_fieldFocusChange(context, _nameFocus, _emailFocus);
},
keyboardType: TextInputType.name,
keyboardAction: TextInputAction.next,
controller: _nameController,
hintText: 'Name',
validator: (value) {
if (value.toString().length <= 2 || value!.isEmpty) {
return 'Enter a valid Name';
}
return '';
},
),
SizedBox(height: 10.h),
RoundedTextFormField(
focusNode: _emailFocus,
onFieldSubmitted: (term) {
_fieldFocusChange(context, _emailFocus, _passwordFocus);
},
keyboardType: TextInputType.emailAddress,
keyboardAction: TextInputAction.next,
controller: _emailController,
hintText: 'Email',
validator: (value) {
bool _isEmailValid =
RegExp(r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+").hasMatch(value!);
if (!_isEmailValid || value.isEmpty) {
return 'Invalid Email';
}
return '';
},
),
SizedBox(height: 10.h),
RoundedTextFormField(
focusNode: _passwordFocus,
onFieldSubmitted: (term) {
_fieldFocusChange(context, _passwordFocus, _passwordConfirmFocus);
},
keyboardType: TextInputType.visiblePassword,
keyboardAction: TextInputAction.next,
obsecureText: true,
controller: _passwordController,
hintText: 'Password',
validator: (value) {
if (value.toString().length < 7 || value!.isEmpty) {
return 'Password should be longer or equal to 7 characters.';
}
return '';
},
),
SizedBox(height: 10.h),
RoundedTextFormField(
focusNode: _passwordConfirmFocus,
keyboardAction: TextInputAction.done,
onFieldSubmitted: (term) {
_passwordConfirmFocus.unfocus();
//Get.to(() => LoginScreen());
},
keyboardType: TextInputType.visiblePassword,
obsecureText: true,
hintText: 'Confirm Password',
validator: (value) {
if (value!.trim() != _passwordController.text.trim() || value.isEmpty) {
return 'Passwords do not match!';
}
return '';
},
),
SizedBox(height: 30.h),
_isLoading
? const CircularProgressIndicator() // TODO custom progress indicator
: VextElevatedButton(
buttonText: 'Sign Up',
onPressed: () {
debugPrint('Signup Submit button Pressed');
if (_signUpFormKey.currentState!.validate()) {
_signUpFormKey.currentState!.save();
setState(() {
_isLoading = true;
});
FocusScope.of(context).unfocus();
String name = _nameController.text.trim();
String email = _emailController.text.trim();
String password = _passwordController.text.trim();
debugPrint('Attempting Signup with Firebase');
_authController.signUp(name, email, password);
setState(() {
_isLoading = false;
});
}
},
),
],
),
);
}
}
_fieldFocusChange(BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
currentFocus.unfocus();
FocusScope.of(context).requestFocus(nextFocus);
}
The few times I got the screen to scroll at all the keyboard would push everything up but when the keyboard would close the page contents would stay at the raised level but scrollable.
Any help would be most appreciated
EDIT*
Here are the 2 custom Widgets that I can think of that are used in the signup screen
roundedTextFormfield
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:vext/helpers/constants.dart';
class RoundedTextFormField extends StatelessWidget {
const RoundedTextFormField({
Key? key,
this.controller,
required this.hintText,
this.obsecureText = false,
required this.validator,
this.keyboardType = TextInputType.text,
this.keyboardAction = TextInputAction.next,
this.focusNode,
this.onFieldSubmitted,
this.autoFocus = false,
this.errorText,
this.onChanged,
this.initialValue,
}) : super(key: key);
final TextEditingController? controller;
final bool? obsecureText;
final String? hintText;
final String? Function(String?) validator;
final TextInputType? keyboardType;
final TextInputAction keyboardAction;
final FocusNode? focusNode;
final Function(String)? onFieldSubmitted;
final bool? autoFocus;
final String? errorText;
final Function(String)? onChanged;
final String? initialValue;
#override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 18.0.w),
child: TextFormField(
initialValue: initialValue,
onChanged: onChanged,
cursorColor: kSecondaryColor,
autofocus: autoFocus!,
keyboardType: keyboardType,
textInputAction: keyboardAction,
focusNode: focusNode,
onFieldSubmitted: onFieldSubmitted,
style: TextStyle(color: Theme.of(context).colorScheme.secondary),
controller: controller,
obscureText: obsecureText!,
decoration: InputDecoration(
errorStyle: TextStyle(
color: Colors.orange,
fontSize: 10.sp,
fontWeight: FontWeight.bold,
),
hintText: hintText,
hintStyle: TextStyle(color: Theme.of(context).colorScheme.secondary),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.secondary,
width: 2.w,
),
borderRadius: BorderRadius.all(
Radius.circular(30.0.r),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).colorScheme.secondary,
width: 2.w,
),
borderRadius: BorderRadius.all(
Radius.circular(30.0.r),
),
),
errorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).errorColor,
width: 2.w,
),
borderRadius: BorderRadius.all(
Radius.circular(30.0.r),
),
),
focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Theme.of(context).errorColor,
width: 2.w,
),
borderRadius: BorderRadius.all(
Radius.circular(30.0.r),
),
),
),
validator: validator,
),
);
}
}
and the other of an elevated button
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
class VextElevatedButton extends StatelessWidget {
const VextElevatedButton({
Key? key,
required this.buttonText,
required this.onPressed,
this.fontSize = 20,
}) : super(key: key);
final String? buttonText;
final double? fontSize;
final VoidCallback onPressed;
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
child: Text(
buttonText!,
style: TextStyle(
fontSize: 20.sp,
),
),
style: ElevatedButton.styleFrom(
elevation: 20,
shadowColor: Theme.of(context).colorScheme.secondary,
minimumSize: Size(context.width * 0.4.w, context.height * 0.065.h),
onPrimary: Theme.of(context).colorScheme.secondary,
textStyle: TextStyle(color: Theme.of(context).colorScheme.secondary),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.r),
side: BorderSide(
width: 2.w,
color: Theme.of(context).colorScheme.secondary,
),
),
),
);
}
}
but these are just the flutter widgets with set options for reusability
Wrap your SignUp class column with SingleChildScrollview after that wrap it up with Container which have property Like Below
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child:SingleChildScrollView(child:Column(your widgets))
)
I am design a screen in which I need to opening a drop down list when user click on textfield till now I am using CupertinoActionSheetAction sheet which is correctly working now I need to replace it with DropdownButton but when I am doing it is not displaying on screen I don't know why.
Here is my code focus on line number 136 (function for CupertinoActionSheetAction is working code) and line 138 where (function for drop not working code) according to me may be it due to build context but I m not sure how to use 'build context' in this context can any one help me out to fix that.
Thanks in advance, And any suggestion for making my code more reusable will be helpful as well :)
import 'dart:ffi';
import 'package:fleet_management/AppContants/Contants.dart';
import 'package:fleet_management/Controllers/NewFuelExpenseController.dart';
import 'package:fleet_management/Models/NewFuelExpenseModel.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AddFuelView extends StatefulWidget {
const AddFuelView({Key? key}) : super(key: key);
#override
_AddFuelView createState() {
return _AddFuelView();
}
}
// MyTripHistoryView
class _AddFuelView extends State<AddFuelView> {
NewFuelExpenseModel fuelExpense =
NewFuelExpenseController().getNewFuelExpense();
DateTime _selectedDate = DateTime.now();
String dropdownvalue = 'Item 1';
// List of items in our dropdown menu
var items = [
'Item 1',
'Item 2',
'Item 3',
'Item 4',
'Item 5',
];
TextStyle _titleTextStyle = const TextStyle();
TextStyle _valueTextStyle = const TextStyle();
final GlobalKey newFuelExpenseFormField = GlobalKey<FormState>();
final TextEditingController _dateEditingController = TextEditingController();
final TextEditingController _priceTextEditingController =
TextEditingController();
final TextEditingController _gallonsTextEditingController =
TextEditingController();
final TextEditingController _totalTextEditingController =
TextEditingController();
final TextEditingController _odometerTextEditingController =
TextEditingController();
final TextEditingController _fuelTypeTextEditingController =
TextEditingController();
final TextEditingController _vendorTextEditingController =
TextEditingController();
#override
void initState() {
super.initState();
_titleTextStyle =
const TextStyle(fontSize: 16, fontWeight: FontWeight.w600);
_valueTextStyle = const TextStyle(
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.black38);
_dateEditingController.text =
"${_selectedDate.day}-${_selectedDate.month}-${_selectedDate.year}";
}
#override
Widget build(BuildContext context) {
var scaffold = Scaffold(
appBar: AppBar(
title: Text(StringsConstants.newFuelExpense),
backgroundColor: AppColorsConstants.primaryColor,
actions: <Widget>[
FlatButton(
textColor: Colors.white,
onPressed: () {
print("SAVE Button Clicked");
},
child: Text("Save", style: _titleTextStyle),
),
],
),
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Form(
key: newFuelExpenseFormField,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
showDateRow(context),
addTextFieldInput(
StringsConstants.priceGallon,
"\u{20B9}0.00",
false,
_priceTextEditingController,
TextInputType.datetime,
null,
null),
addTextFieldInput(
StringsConstants.gallons,
"",
false,
_gallonsTextEditingController,
TextInputType.number,
null,
null),
addTextFieldInput(
StringsConstants.total,
"\u{20B9}0.00",
false,
_totalTextEditingController,
TextInputType.number,
null,
null),
addTextFieldInput(
StringsConstants.odometer,
"",
false,
_odometerTextEditingController,
TextInputType.number,
null,
null),
// show action sheet
addTextFieldInput(
StringsConstants.fuelType,
"",
true,
_fuelTypeTextEditingController,
TextInputType.none,
null, () {
// Working. - >>>> HERE <<<<<
showActionSheet(context);
// Not Working >>>> HERE <<<<< Uncomment following function before
// showDropDown();
}),
addTextFieldInput(
StringsConstants.vendor,
"",
false,
_vendorTextEditingController,
TextInputType.text,
null,
null),
const SizedBox(
height: 50,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
print("Submit button pressed!");
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24),
primary: AppColorsConstants.primaryColor,
textStyle:
const TextStyle(fontWeight: FontWeight.bold),
),
child: Text(StringsConstants.submit)),
ElevatedButton(
onPressed: () {
print("Cancel button pressed!");
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 24),
primary: AppColorsConstants.primaryColor,
textStyle:
const TextStyle(fontWeight: FontWeight.bold),
),
child: Text(StringsConstants.cancel))
],
)
],
),
),
),
),
),
);
return scaffold;
}
void showDropDown() {
DropdownButton<String>(
items: <String>['A', 'B', 'C', 'D'].map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (_) {},
);
}
Future<dynamic> showActionSheet(BuildContext context) {
return showCupertinoModalPopup(
context: context,
builder: (BuildContext context) => CupertinoActionSheet(
title: const Text('Choose Options'),
actions: <Widget>[
CupertinoActionSheetAction(
child: const Text('Oil'),
onPressed: () {
_fuelTypeTextEditingController.text = "Oil";
Navigator.pop(context, 'Oil');
},
),
CupertinoActionSheetAction(
child: const Text('Petrol'),
onPressed: () {
_fuelTypeTextEditingController.text = "Petrol";
Navigator.pop(context, 'Petrol');
},
),
CupertinoActionSheetAction(
child: const Text('diesel'),
onPressed: () {
_fuelTypeTextEditingController.text = "diesel";
Navigator.pop(context, 'diesel');
},
)
],
cancelButton: CupertinoActionSheetAction(
child: const Text('Cancel'),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context, 'Cancel');
},
)),
);
}
Container addTextFieldInput(
String title,
String initialValue,
bool isEditable,
TextEditingController textfieldController,
TextInputType keyboardType,
FormFieldValidator<String>? validator,
GestureTapCallback? tabCallback,
) {
return Container(
padding: const EdgeInsets.fromLTRB(0, 16, 0, 8),
child: SizedBox(
child: TextFormField(
onTap: tabCallback,
keyboardType: keyboardType,
cursorHeight: 16,
cursorWidth: 1.4,
readOnly: isEditable,
controller: textfieldController,
validator: validator,
decoration: InputDecoration(
isDense: true,
floatingLabelStyle:
TextStyle(color: AppColorsConstants.primaryColor),
labelText: title,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: AppColorsConstants.primaryColor, width: 1.5),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black38, width: 1.5),
),
border: const OutlineInputBorder()),
style: const TextStyle(fontSize: 18),
cursorColor: Colors.black38,
showCursor: true,
autofocus: true,
),
),
);
}
Container showDateRow(BuildContext context) {
return Container(
child: TextFormField(
onTap: () => {_selectDate(context)},
cursorHeight: 16,
cursorWidth: 1.4,
readOnly: true,
enableInteractiveSelection: false,
controller: _dateEditingController,
decoration: InputDecoration(
isDense: true,
labelStyle: const TextStyle(color: Colors.orangeAccent),
labelText: StringsConstants.date,
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.orangeAccent, width: 1.5),
),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.black38, width: 1.5),
),
border: const OutlineInputBorder()),
style: const TextStyle(fontSize: 18),
cursorColor: Colors.black38,
showCursor: true,
autofocus: true,
),
);
}
Future<void> _selectDate(BuildContext context) async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(1990),
lastDate: DateTime.now());
if (picked != null && picked != _selectedDate) {
setState(() {
_selectedDate = picked;
this._dateEditingController.text =
"${_selectedDate.day}-${_selectedDate.month}-${_selectedDate.year}";
});
}
}
}
For DropDown in flutter you need
an initail value,
a list to be shown just
String selectedvalue='myvalue';
/// be sure you add the variable value in the 0 index of you list other wise it will thrown error or exception..
List<String> myList=[
'myvalue',/// the value is same as variable value
'othe value', ....
];
DropDownButton(
onChanged: (resultValue){
/// you can get selected value from here
},
items: myList.map((e){
retrun DropdownMenuItem(
value: e,
child: Text(e));
}).toList(),
value: selectedvalue,
),
You can use DropdownButtonFormField in place of TextFormField and can make some style related changes per your requirement.
class MyWidget extends StatelessWidget {
String selectedValue = "USA";
List<DropdownMenuItem<String>> get dropdownItems{
List<DropdownMenuItem<String>> menuItems = [
DropdownMenuItem(child: Text("USA"),value: "USA"),
DropdownMenuItem(child: Text("Canada"),value: "Canada"),
DropdownMenuItem(child: Text("Brazil"),value: "Brazil"),
DropdownMenuItem(child: Text("England"),value: "England"),
];
return menuItems;
}
#override
Widget build(BuildContext context) {
return DropdownButtonFormField(
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(20),
),
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 2),
borderRadius: BorderRadius.circular(20),
),
filled: true,
fillColor: Colors.blueAccent,
),
dropdownColor: Colors.blueAccent,
value: selectedValue,
onChanged: (String? newValue) {
selectedValue = newValue!;
},
items: dropdownItems);
}
}
I'm trying to write construction for button enable after 13 symbols are written. But my symbols in TextField won't delete/write. If I delete setState, I can correctly write/delete symbols but my button doesn't work. What I can do, for all correctly work?
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MobileNumberState();
}
class _MobileNumberState extends State<MyApp> {
var _isDisable = false;
var _phone = '+996';
final String wayMainLogo = 'assets/images/test.svg';
........................
Row(
children: [
Expanded(
flex: 1,
child: Container(
margin: const EdgeInsets.fromLTRB(47.0, 50, 47, 0),
child: TextField(
// autofocus: false,
onChanged: (textInField) {
if (textInField.length == 13) {
setState(() {
_phone = textInField;
_isDisable = true;
});
} else if (textInField.length < 13) {
setState(() {
_phone = textInField;
_isDisable = false;
});
}
},
controller: TextEditingController(
text: _phone,
),
inputFormatters: [
LengthLimitingTextInputFormatter(13),
],
keyboardType: TextInputType.number,
maxLength: 13,
decoration: const InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
),
labelText: '+996 XXX YYY YYY',
labelStyle: TextStyle(
color: Colors.grey,
)),
))),
],
),
Row(
children: [
Expanded(
flex: 1,
child: Container(
margin: const EdgeInsets.fromLTRB(47.0, 50, 47, 0),
child: ElevatedButton(
onPressed: _isDisable ? () {} : null,
child: const Text('Далее'),
))),
],
),
Do some changes like-
define TextEditingController textController = TextEditingController();
controller: textController,
Hope, it will work.
Try to remove text from the controller.
controller: TextEditingController(),
Minimum 1 alphabetic
Minimum 1 number
Allow only Character (_)
its failed
Pattern pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[_]).{8,}$';
RegExp regex = new RegExp(pattern);
Just check out this example that i have created :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController userName = TextEditingController();
FocusNode usernameFocus = new FocusNode();
String errorText;
bool _isValid = false;
#override
void initState() {
super.initState();
userName.addListener(() {
String pattern = r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[_]).{8,}$';
RegExp regExp = new RegExp(pattern);
if (userName.text.isEmpty) {
setState(() {
errorText = 'Field cannot be empty';
});
} else {
if (!regExp.hasMatch(userName.text)) {
print('The does not matches the requirement');
setState(() {
// here you can add you text
errorText =
'Minimum 1 Capital letter, 1 small letter and 1 number and _';
_isValid = false;
});
} else {
print('the value matches');
setState(() {
errorText = null;
_isValid = true;
});
}
}
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: TextField(
focusNode: usernameFocus,
decoration: new InputDecoration(
errorText: errorText,
prefixIcon: Icon(
Icons.supervised_user_circle,
color: Color(0xFF282858),
),
labelText: "UserName",
labelStyle: TextStyle(
fontFamily: "Poppins-Medium",
color: usernameFocus.hasFocus
? Colors.grey[600]
: Colors.grey[600]),
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[400], width: 2.0),
borderRadius: BorderRadius.circular(10.0),
),
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
borderSide:
new BorderSide(color: Colors.grey[400], width: 2.0),
),
//fillColor: Colors.green
),
controller: userName,
keyboardType: TextInputType.text,
),
),
RaisedButton(
child: Text('Login'),
onPressed: () {
print(_isValid);
if (!_isValid) {
return;
}
print('validation sucess');
},
)
],
)),
),
);
}
}
let me know if it works.
You would need to use a validator on your Textfield. You would add a condtion in the validator function to check if it's false and returns the error meessage that you would like the user to see.
You can either validate by using autovalidate: true, or you can do it manualy by using .currentState.validate() on your form before saving.
so your code could look something like this
validator: (value) {
final alphanumeric = RegExp(YOUR_REGEX_HERE);
if (!alphanumeric.hasMatch(value)) return 'YOUR_ERROR_MESSAGE';
}
You can use this library
pubspec.yaml
flutter_form_builder: ^3.7.3
Code will be like this:
GlobalKey _addextKey = GlobalKey();
FormBuilder(
key: _addextKey,
child: ListView(
children: <Widget>[
TextFormField(
textInputAction: TextInputAction.next,
style: textStyle,
controller: _NameauthController,
// ignore: missing_return
validator: FormBuilderValidators.required(),
decoration: InputDecoration(
hintText: 'name',
hintStyle: TextStyle(fontSize: 12.0),
labelStyle: textStyle,
errorStyle:
TextStyle(color: Colors.red, fontSize: 12.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0))),
keyboardType: TextInputType.text,
),
]);),
What I need to do is when the onPressed is called, I get the Textfield error when I don't enter text.
class _ExampleDialogTextState extends State<ExampleDialogText> {
FocusNode focusNode = FocusNode();
final textController = TextEditingController();
bool noText = false;
String nameList = "";
#override
void initState() {
super.initState();
nameList = "";
focusNode.addListener(() {
if (!focusNode.hasFocus) {
setState(() {
noText = nameList.length == 0;
});
FocusScope.of(context).requestFocus(focusNode);
}
});
}
TextField(
focusNode: focusNode,
autofocus: true,
controller: textController,
style: TextStyle(
color: Colors.black, fontSize: 14),
decoration: InputDecoration(
counterText: '',
errorText:
noText ? 'Value Can\'t Be Empty' : null,)
RaisedButton(
onPressed: () {
setState(() {
nameList.isEmpty
? noText = true
: noText = false;
});
},)
}
But still, with that code it doesn't work for me. Attached here is the entire class
code
Thank you!
Your Code is correct but you can not update state in ShowDialog Widget, so you have to return Statetful Widget in ShowDialog.
I added whole code which i change.
import 'package:flutter/material.dart';
class Consts {
Consts._();
static const double padding = 16.0;
static const double buttonPadding = 5.0;
}
class DeleteWidget extends StatefulWidget {
const DeleteWidget({Key key}) : super(key: key);
#override
_DeleteWidgetState createState() => _DeleteWidgetState();
}
class _DeleteWidgetState extends State<DeleteWidget> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueAccent,
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialogNameList();
},
backgroundColor: Colors.orange,
child: Icon(
Icons.add,
color: Colors.purple,
size: 40,
),
),
);
}
showDialogNameList() {
return showDialog(
context: context,
builder: (context) {
return CustomeDialog1();
});
}
}
class CustomeDialog1 extends StatefulWidget {
CustomeDialog1({Key key}) : super(key: key);
#override
_CustomeDialog1State createState() => _CustomeDialog1State();
}
class _CustomeDialog1State extends State<CustomeDialog1> {
FocusNode focusNode = FocusNode();
final textController = TextEditingController();
bool noText = false;
String nameList = "";
#override
void initState() {
super.initState();
nameList = "";
focusNode.addListener(() {
if (!focusNode.hasFocus) {
setState(() {
noText = nameList.length == 0;
});
FocusScope.of(context).requestFocus(focusNode);
}
});
}
#override
Widget build(BuildContext context) {
var screenHeight = MediaQuery.of(context).size.height;
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(Consts.padding),
),
elevation: 0.0,
child: Container(
height: screenHeight / 3,
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
top: Consts.padding,
bottom: Consts.padding,
left: Consts.padding,
right: Consts.padding,
),
margin: EdgeInsets.only(top: 0),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(Consts.padding),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10.0,
offset: const Offset(0.0, 10.0),
),
],
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
TextField(
focusNode: focusNode,
autofocus: true,
controller: textController,
cursorColor: Colors.white,
style: TextStyle(color: Colors.black, fontSize: 14),
decoration: InputDecoration(
counterText: '',
errorText: noText ? 'Value Can\'t Be Empty' : null,
hintText: 'List Name',
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.black),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.green),
),
labelStyle: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
),
onChanged: (String text) {
nameList = text;
},
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 150.0,
height: 45.0,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onPressed: () {
setState(() {
nameList.isEmpty
? noText = true
: noText = false;
});
},
padding:
EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
color: Color(0xFF2DA771),
child: Text('Add',
style: TextStyle(
color: Colors.white,
fontFamily: 'Roboto',
fontSize: 16)),
),
),
],
),
)
],
),
),
)
],
),
));
}
}