Flutter inkwell ontap not reacting - flutter

I want to ask why my ontap not working on my code , I'm creating separate function and I wanted to call it inside my textformfield which is in another separate function, I'm new and still learning , please help me.
this is my code
_showTaskCategoriesDial({required Size size}) {
showDialog(
context: context,
builder: (ctx) {
return AlertDialog(
backgroundColor: Colors.black54,
title: Text(
'Job Category',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 20),
),
content: Container(
width: size.width * 0.9,
child: ListView.builder(
shrinkWrap: true,
itemCount: Persistent.jobCategoryList.length,
itemBuilder: (ctx, index) {
return InkWell(
onTap: () {
setState(() {
_jobCategoryController.text =
Persistent.jobCategoryList[index];
});
Navigator.pop(context);
},
child: Row(
children: [
const Icon(
Icons.arrow_right_alt_outlined,
color: Colors.grey,
),
Padding(
padding: EdgeInsets.all(8.0),
child: Text(
Persistent.jobCategoryList[index],
style: TextStyle(
color: Colors.grey,
fontSize: 16,
),
),
)
],
),
);
},
),
),
);
});
}
and then I call it in my textFormFields like so and I don't know why it doesn't work
_textFormFields(
valueKey: 'JobCategory',
controller: _jobCategoryController,
enabled: false,
fct: () {
_showTaskCategoriesDial(size: size);
},
this is my textFormFields class
Widget _textFormFields(
{required String valueKey,
required TextEditingController controller,
required bool enabled,
required Function fct,
required int maxlength}) {
return Padding(
padding: EdgeInsets.all(5.0),
child: InkWell(
onTap: () {
fct;
},
child: TextFormField(
validator: (value) {
if (value!.isEmpty) {
return 'Value is missing';
}
return null;
},
controller: controller,
enabled: enabled,
key: ValueKey(valueKey),
style: TextStyle(
color: Colors.white,
),
maxLines: valueKey == 'JobDescription' ? 3 : 1,
maxLength: maxlength,
keyboardType: TextInputType.text,
decoration: InputDecoration(
filled: true,
fillColor: Colors.black54,
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.black)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.black,
),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red))),
),
),
);
}

Change this:
Widget _textFormFields(
{required String valueKey,
required TextEditingController controller,
required bool enabled,
required Function fct,
required int maxlength}) {
return Padding(
padding: EdgeInsets.all(5.0),
child: InkWell(
onTap: () {
fct;
},
child: TextFormField(
...
),
...
)
to:
Widget _textFormFields(
{required String valueKey,
required TextEditingController controller,
required bool enabled,
required Function()? fct, // <---- change this
required int maxlength}) {
return Padding(
padding: EdgeInsets.all(5.0),
child: InkWell(
onTap: fct, // <---- change this
child: TextFormField(
...
),
...
)
or :
InkWell(
onTap: (){
fct(); // <---- change this
},
child: TextFormField(
...
),
)

Related

Flutter ListView can't tap items

I'm using flutter_maps map and overlaying a custom search bar with drop down menu. When user searches, locations appear and should be clickable. Using the below code, the UI appears, but clicks aren't possible and nothing happens. I've also noticed the list view can't be scrolled either, can anyone see what the issue is?
List<Widget> _locations = [];
Future<void> searchLocations(String input) async {
final database =
await $FloorLocalDatabase.databaseBuilder('local_database.db').build();
final locationsDao = database.locationDao;
locationsDao.searchLocations(input).then((value) => {
setState(() {
_locations = [];
value.forEach((element) {
_locations.add(locationItem(element));
});
})
});
}
#override
Widget build(BuildContext context) {
return FlutterMap(
options: MapOptions(
center: LatLng(51.5072, -0.1276),
zoom: zoom,
interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag,
),
children: [
TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png"),
MarkerLayer(markers: _markers),
Padding(
padding:
const EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
child: SizedBox(
height: 56.0,
child: Card(
shape: roundedCorner32,
elevation: 6.0,
child: Wrap(children: [
Column(children: [
TextField(
cursorColor: Theme.of(context).colorScheme.secondary,
decoration: InputDecoration(
contentPadding: const EdgeInsets.only(left: 16.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(32.0),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
)),
filled: true,
hintStyle: TextStyle(color: Colors.grey[800]),
hintText: search,
fillColor: Colors.white),
onChanged: (value) {
searchLocations(value);
},
),
if (_locations.isNotEmpty) ...[
Card(
color: Theme.of(context).colorScheme.primary,
shape: roundedCorner16,
elevation: 6.0,
child: Wrap(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
padding: EdgeInsets.all(8.0),
color: Theme.of(context).colorScheme.primary,
child: ListView.separated(
shrinkWrap: true,
itemCount: _locations.length,
itemBuilder:
(BuildContext context, int index) {
return GestureDetector(
onTap: () {
print("XXXXXXXXXXX");
},
child: _locations[index],
);
}, separatorBuilder: (BuildContext context, int index) {
return const SizedBox(height: 8.0);
},),
),
),
]),
)
]
]),
]),
),
)),
]);
}
Widget locationItem(Location location) {
return AutoSizeText(buildFullLocation(location), maxLines: 1);
}
How about try wrap the TextFiled widget in an Inkwell or GestureDetector widget?
GestureDetector(
onTap: (){},
child: TextField()),

Flutter Image Picker to Image URL

i have the following code below. ive used image_picker package to upload pictures to be used as profile pictures. ive commented my previous code that uses an image url instead. my question is if there's a way to convert the images uploaded to images url, that way, i can display the profile picture when i get into the home screen.
// ignore_for_file: use_build_context_synchronously, deprecated_member_use
import 'dart:io';
import 'package:cloud_functions/cloud_functions.dart';
import 'package:firebase_auth/firebase_auth.dart' as firebase;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:ibchat/pages/verify_email_page.dart';
import 'package:ibchat/screens/screens.dart';
import 'package:ibchat/theme.dart';
import 'package:image_picker/image_picker.dart';
import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart';
import '../app.dart';
class SignUpScreen extends StatefulWidget {
static Route get route => MaterialPageRoute(
builder: (context) => const SignUpScreen(),
);
const SignUpScreen({Key? key}) : super(key: key);
#override
State<SignUpScreen> createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final auth = firebase.FirebaseAuth.instance;
final functions = FirebaseFunctions.instance;
final _formKey = GlobalKey<FormState>();
PickedFile? _imageFile;
final ImagePicker _picker = ImagePicker();
//final _profilePictureController = TextEditingController();
final _nameController = TextEditingController();
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _designationController = TextEditingController();
final _companyController = TextEditingController();
final _emailRegex = RegExp(
r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+#[a-zA-Z0-9]+\.[a-zA-Z]+");
bool _loading = false;
Future<void> _signUp() async {
if (_formKey.currentState!.validate()) {
setState(() {
_loading = true;
});
try {
// Authenticate with Firebase
final creds =
await firebase.FirebaseAuth.instance.createUserWithEmailAndPassword(
email: _emailController.text,
password: _passwordController.text,
);
final user = creds.user;
if (user == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Member not found')),
);
return;
}
// Set Firebase display name and profile picture
List<Future<void>> futures = [
/*if (_profilePictureController.text.isNotEmpty)
creds.user!.updatePhotoURL(_profilePictureController.text),*/
/*if (_picker.toString().isNotEmpty)
creds.user!.updatePhotoURL(_picker.toString()),*/
creds.user!.updateDisplayName(_nameController.text),
];
await Future.wait(futures);
// Create Stream user and get token using Firebase Functions
final callable = functions.httpsCallable('createStreamUserAndGetToken');
final results = await callable();
// Connect user to Stream and set user data
final client = StreamChatCore.of(context).client;
await client.connectUser(
User(
//image: _profilePictureController.text,
//image: _picker.toString(),
id: creds.user!.uid,
name: _nameController.text,
extraData: {
"email": _emailController.text,
"designation": _designationController.text,
"company": _companyController.text,
}),
results.data,
);
// Navigate to verify email page
await Navigator.of(context).pushReplacement(VerifyEmailPage.route);
} on firebase.FirebaseAuthException catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(e.message ?? 'Verification error')),
);
} catch (e, st) {
logger.e('Sign up error', e, st);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
backgroundColor: Colors.red, content: Text('An error occured')),
);
}
setState(() {
_loading = false;
});
}
}
String? _nameInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Name cannot be empty';
}
return null;
}
String? _emailInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Email cannot be empty';
}
if (!_emailRegex.hasMatch(value)) {
return 'Not a valid email';
}
return null;
}
String? _passwordInputValidator(String? value) {
if (value == null || value.isEmpty) {
return 'Password Cannot be empty';
}
if (value.length <= 6) {
return 'Password needs to be longer than 6 characters';
}
return null;
}
#override
void dispose() {
//_profilePictureController.dispose();
_nameController.dispose();
_emailController.dispose();
_passwordController.dispose();
_designationController.dispose();
_companyController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Image.asset('assets/images/logo.png', scale: 2),
backgroundColor: Colors.transparent,
),
body: (_loading)
? const Center(
child: SizedBox(
height: 100,
width: 100,
child: CircularProgressIndicator(color: AppColors.accent)))
: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
onWillPop: () async => false,
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(bottom: 24),
child: Text(
'Registeration',
style: GoogleFonts.lato(
fontSize: 28, fontWeight: FontWeight.w800),
),
),
/*Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _profilePictureController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Picture URL',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.url,
),
),*/
imageProfile(),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _nameController,
validator: _nameInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Name',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
autofillHints: const [
AutofillHints.name,
AutofillHints.username
],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _emailController,
validator: _emailInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Email',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.emailAddress,
autofillHints: const [AutofillHints.email],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _passwordController,
validator: _passwordInputValidator,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Password',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
obscureText: true,
enableSuggestions: false,
autocorrect: false,
keyboardType: TextInputType.visiblePassword,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _designationController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Designation',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: TextFormField(
controller: _companyController,
decoration: const InputDecoration(
focusedBorder: UnderlineInputBorder(
borderSide:
BorderSide(color: AppColors.accent, width: 2),
),
hintText: 'Company',
hintStyle: TextStyle(fontSize: 17),
),
style: const TextStyle(fontSize: 17),
keyboardType: TextInputType.name,
),
),
const SizedBox(height: 30),
Padding(
padding: const EdgeInsets.all(12.0),
child: SizedBox(
height: 50,
width: 250,
child: ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
))),
onPressed: _signUp,
child: Text('Sign Up',
style: GoogleFonts.lato(
fontSize: 21,
fontWeight: FontWeight.bold,
color: Colors.black)),
),
),
),
const SizedBox(
height: 20,
),
const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Divider(),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Already a Member?',
style: Theme.of(context).textTheme.subtitle2),
const SizedBox(width: 8),
TextButton(
style: TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0)),
primary: AppColors.accent),
onPressed: () {
Navigator.of(context).push(SignInScreen.route);
},
child: const Text('Sign In',
style: TextStyle(color: AppColors.secondary)),
),
],
),
],
),
),
),
),
);
}
Widget imageProfile() {
return Center(
child: Stack(
children: <Widget>[
CircleAvatar(
radius: 34,
backgroundImage: _imageFile == null
? const AssetImage("assets/images/profile_default.png")
as ImageProvider
: FileImage(File(_imageFile!.path)),
),
Positioned(
bottom: -2,
right: -1,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet()),
);
},
child: const Icon(CupertinoIcons.camera_fill,
color: AppColors.accent, size: 20)),
)
],
),
);
}
Widget bottomSheet() {
return Container(
height: 100,
width: MediaQuery.of(context).size.width,
margin: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: <Widget>[
const Text(
"Upload a Profile Photo",
style: TextStyle(
fontSize: 18.0,
),
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon: const Icon(CupertinoIcons.camera_fill),
onPressed: () {
takePhoto(ImageSource.camera);
},
label: const Text("Camera")),
FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
icon:
const Icon(CupertinoIcons.photo_fill_on_rectangle_fill),
onPressed: () {
takePhoto(ImageSource.gallery);
},
label: const Text("Photos")),
],
)
],
));
}
void takePhoto(ImageSource source) async {
final pickedFile = await _picker.getImage(source: source);
setState(() {
_imageFile = pickedFile!;
});
}
}

Drop down widget is not showing in flutter

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 am making a contacts book application but when I save contacts the name is not displayed

This my contacts list page
class Contacts extends StatefulWidget with NavigationStates {
#override
_ContactsState createState() => _ContactsState();
}
class _ContactsState extends State<Contacts>{
DatabaseHelper databaseHelper = DatabaseHelper();
List<contacts> contactsList;
int count = 0;
#override
Widget build(BuildContext context, ) {
if(contactsList == 0){
contactsList = List<contacts>();
updateListView();
}
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text("Contacts"),
backgroundColor: Colors.lightGreenAccent,
centerTitle: true,
),
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(4.0),
margin: EdgeInsets.all(5.0),
child: TextField(
//controller: searchController,
decoration: InputDecoration(
labelText:'Search Contacts',
border: new OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25)),
borderSide: new BorderSide(
color: Colors.pinkAccent
)
),
prefixIcon: Icon(
Icons.search,
color: Colors.black,
)
),
),
),
Expanded(
child: ListView.builder(
itemCount: count,
itemBuilder: (context , int position){
return Card(
elevation: 1.0,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.pinkAccent,width: 1),
borderRadius: BorderRadius.circular(20)
),
child: Container(
margin: EdgeInsets.all(6.0),
padding: EdgeInsets.all(4.0),
color: Colors.white,
child: ListTile(
leading: CircleAvatar(
radius: 30.0,
backgroundColor: Colors.lightBlueAccent,
child: Icon(Icons.person,color: Colors.black,),
),
title: Text(this.contactsList[position].first_name,style: TextStyle(color: Colors.black,fontSize: 28.0),),
subtitle: Text(this.contactsList[position].last_name,style:TextStyle(color: Colors.black38,fontSize: 15.0),),
trailing: GestureDetector(
child: Icon(Icons.delete, color: Colors.pinkAccent,),
onTap: () {
_delete(context, contactsList[position]);
},
),
),
),
);
},
),
)
],
),
floatingActionButton: new FloatingActionButton(onPressed: null,
child: new Icon(Icons.dialpad,color: Colors.black,size: 30,),
backgroundColor: Colors.pinkAccent,
),
bottomNavigationBar: CurvedNavigationBar(
color: Colors.lightGreenAccent,
backgroundColor: Colors.white,
buttonBackgroundColor: Colors.pinkAccent,
height: 50,
index: 1,
items:<Widget>[
Icon(Icons.call,size: 25,color: Colors.black,),
Icon(Icons.home,size: 30,color: Colors.black,),
Icon(Icons.person_add_rounded,size: 25,color: Colors.black,),
],
animationDuration: Duration(
milliseconds: 400
),
animationCurve: Curves.easeIn,
onTap: (index) async {
if (index == 0)
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return logs();
}
)
);
if (index == 1)
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) {
return Contacts();
}
)
);
if (index == 2)
navigateToDetail(contacts('',''));
}
),
);
}
updateListView() {
final Future<Database> dbFuture = databaseHelper.initalizeDatabase();
dbFuture.then((database) {
Future<List<contacts>> contactsListFuture = databaseHelper.getContactList();
contactsListFuture.then((contactsList){
setState(() {
this.contactsList = contactsList;
this.count = contactsList.length;
});
});
});
}
Color getStorageColor() {
int storage;
switch (storage) {
case 1:
return Colors.pinkAccent;
break;
case 2:
return Colors.lightBlueAccent;
break;
default:
return Colors.lightBlueAccent;
}
}
void navigateToDetail(contacts contact) async{
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
return AddContacts(contact);
}));
if (result == true) {
updateListView();
}
}
void _delete(BuildContext context, contacts contact) async {
int result = await databaseHelper.deleteContact(contact.id);
if (result != 0) {
_SnackBar(context, 'Contact Deleted Successfully');
updateListView();
}
}
void _SnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
content: Text(message),
action: SnackBarAction(
label: 'Undo',
onPressed: (){},
),
);
// ignore: deprecated_member_use
Scaffold.of(context).showSnackBar(snackBar);
}
}
This is my contacts details page
import 'dart:io';
//import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
//import 'package:sqflite/sqflite.dart';
import 'package:mycontacts_app/models/Contact.dart';
import 'dart:async';
import 'package:mycontacts_app/utils/database_helper.dart';
//import 'package:intl/intl.dart';
class AddContacts extends StatefulWidget {
final contacts contact;
AddContacts(this.contact);
//AddContacts(contacts contact);
#override
State<StatefulWidget> createState() {
// _AddContactsState();
return _AddContactsState(this.contact);
}
}
class _AddContactsState extends State<AddContacts> {
//TextEditingController _fnameController,_numberController,_lnameController;
DatabaseHelper helper = DatabaseHelper();
PickedFile _imageFile;
final ImagePicker _picker = ImagePicker();
_AddContactsState(this.contact);
TextEditingController _fnameController = TextEditingController();
TextEditingController _numberController = TextEditingController();
TextEditingController _lnameController = TextEditingController();
contacts contact;
List _Storage = ['Phone','Sim'];
//String _storageval;
#override
Widget build(BuildContext context) {
//_nameController = contacts.first_name
_fnameController.text = contact.first_name;
_lnameController.text = contact.last_name;
_numberController.text = contact.phone_no as String;
return Scaffold(
appBar: AppBar(
title: Text("New Contact"),
backgroundColor: Colors.lightGreenAccent,
centerTitle: true,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 40.0,
horizontal: 10.0,
),
//margin: EdgeInsets.all(15),
child: Form(
child: Column(
//crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Container(
padding: EdgeInsets.only(left: 16.0,right: 16.0),
decoration: BoxDecoration(
border: Border.all(
color: Colors.white
),
borderRadius: BorderRadius.circular(20.0),
),
child: DropdownButton(
hint: Text('Store In '),
dropdownColor: Colors.black12,
elevation: 5,
icon: Icon(Icons.arrow_drop_down),
iconSize: 20.0,
isExpanded: true,
style: TextStyle(
color: Colors.black,fontSize: 18.0
),
items: _Storage.map((value){
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
value: getStorageAsString(contact.storage),
onChanged: (value){
setState(() {
//_storageval = value;
updateStorageAsInt(value);
});
},
),
),
),
imageProfile(),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _fnameController,
onChanged: (value){
updateFirstname();
},
decoration: InputDecoration(
hintText: 'First Name',
prefixIcon: Icon(Icons.person),
//prefixText: "Name",
suffixIcon: Icon(Icons.keyboard_arrow_down),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
contentPadding: EdgeInsets.all(15),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _lnameController,
onChanged: (value){
updateLastName();
},
decoration: InputDecoration(
hintText: 'Last Name',
prefixIcon: Icon(Icons.person),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
fillColor: Colors.white,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
contentPadding: EdgeInsets.all(15),
),
),
),
// SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _numberController,
onChanged: (value){
//updateNumber();
},
decoration: InputDecoration(
hintText: 'Number',
prefixIcon: Icon(Icons.phone_android),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Address',
prefixIcon: Icon(Icons.location_on_rounded),
//prefixText: "Name",
suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Email',
prefixIcon: Icon(Icons.email),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Website',
prefixIcon: Icon(Icons.language),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
//SizedBox(height: 15),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
//controller: _nameController,
decoration: InputDecoration(
hintText: 'Work Info',
prefixIcon: Icon(Icons.business),
//prefixText: "Name",
//suffixIcon: Icon(Icons.keyboard_arrow_down),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
),
fillColor: Colors.white,
filled: true,
contentPadding: EdgeInsets.all(15),
),
),
),
/*ListView.builder(
itemBuilder: (context, index){
return ExpansionTile(
title: ListTile(
title: TextField(
decoration: InputDecoration(
hintText: "Name"
),
style: TextStyle(
color: Colors.black,
fontSize: 15.0,
),
),
),
children: <Widget>[
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Name Prefix"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: " First Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: " Middle Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Last Name"
),
)
),
ListTile(
title:TextFormField(
decoration: InputDecoration(
hintText: "Name Suffix"
),
)
)
],
);
}
)*/
Padding(
padding: const EdgeInsets.only(top: 15.0, bottom: 15.0),
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
color: Colors.lightGreenAccent,
textColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(color: Colors.pinkAccent),
),
onPressed: () {
debugPrint("Save button clicked");
_save();
},
child: Text(
"Save"
),
),
),
Container(width: 5.0,),
Expanded(
child: RaisedButton(
color: Colors.lightGreenAccent,
textColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18.0),
side: BorderSide(color: Colors.pinkAccent),
),
onPressed: () {
_delete();
},
child: Text(
"Cancel"
),
),
)
],
),
)
],
),
),
),
),
);
}
Widget imageProfile() {
return Center(
child: Stack(
children: <Widget>[
CircleAvatar(
radius: 50.0,
backgroundImage: _imageFile==null? AssetImage("assets/default.png"):FileImage(File(_imageFile.path)),
),
Positioned(
bottom: 20.0,
right: 20.0,
child: InkWell(
onTap: () {
showModalBottomSheet(
context: context,
builder: ((builder) => bottomSheet()),
);
},
child: Icon(
Icons.camera_alt,
color: Colors.lightGreenAccent,
size: 28.0,
),
),
),
],
),
);
}
Widget bottomSheet() {
return Container(
height: 100.0,
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.symmetric(
horizontal: 20,
vertical: 20,
),
child: Column(
children: <Widget>[
Text(
"Choose Contact Image",
style: TextStyle(
fontSize: 20,
),
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton.icon(
icon: Icon(Icons.camera),
onPressed: (){
takePhoto(ImageSource.camera);
},
label: Text("Camera"),
),
FlatButton.icon(
icon: Icon(Icons.image),
onPressed: (){
takePhoto(ImageSource.gallery);
},
label: Text("Gallery"),
)
],
)
],
),
);
}
void takePhoto(ImageSource source) async {
final pickedFile = await _picker.getImage(
source: source,
);
setState(() {
_imageFile = pickedFile;
});
}
void updateFirstname(){
contact.first_name = _fnameController.text;
}
// Update the description of Note object
void updateLastName() {
contact.last_name = _lnameController.text;
}
/*void updateNumber() {
contact.phone_no = _numberController.text as int;
}*/
void _save() async {
moveToLastScreen();
//n.date = DateFormat.yMMMd().format(DateTime.now());
int result;
if (contact.id != null) { // Case 1: Update operation
result = await helper.updateContact(contact);
} else { // Case 2: Insert Operation
result = await helper.insertContact(contact);
}
if (result != 0) { // Success
_showAlertDialog('Status', 'Contact Saved Successfully');
} else { // Failure
_showAlertDialog('Status', 'Problem Saving Contact');
}
}
void moveToLastScreen() {
//Navigator.pop(context);
Navigator.pop(context, true);
}
void _delete() async {
moveToLastScreen();
// Case 1: If user is trying to delete the NEW NOTE i.e. he has come to
// the detail page by pressing the FAB of NoteList page.
if (contact.id == null) {
_showAlertDialog('Status','No Contact was deleted');
return;
}
// Case 2: User is trying to delete the old note that already has a valid ID.
int result = await helper.deleteContact(contact.id);
if (result != 0) {
_showAlertDialog('Status','Contact Deleted Successfully');
} else {
_showAlertDialog('Status', 'Error Occured while Deleting Contact');
}
}
void _showAlertDialog(String title, String message) {
AlertDialog alertDialog = AlertDialog(
title: Text(title),
content: Text(message),
);
showDialog(
context: context,
builder: (_) => alertDialog
);
}
void updateStorageAsInt(String value) {
switch (value) {
case 'Phone':
contact.storage = 1;
break;
case 'Sim':
contact.storage = 2;
break;
}
}
// Convert int priority to String priority and display it to user in DropDown
String getStorageAsString(int value) {
String storage;
switch (value) {
case 1:
storage = _Storage[0]; // 'High'
break;
case 2:
storage = _Storage[1]; // 'Low'
break;
}
return storage;
}
}
The contact card and icon is displayed but the name is not displaying.
I was even getting error like :-
This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
It is not even showing the position or file of error
And I am not being able to solve the error .

Flutter : How to do this kind of UI in Flutter to select dates

Hello Friends,
Can someone guide me to do this kind of UI making in flutter?
Thanks in advance...
I hope this code will work for you. You just need to add your datepicker logic on this textfield.
body: Container(
child: Row(
children: [
Container(
width: 5,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Start Date"),
GestureDetector(
onTap: () {
selectDate(context);
},
child: AbsorbPointer(
absorbing: true,
child: TextFormField(
style: TextStyle(color: Colors.black),
controller: startdata,
decoration: InputDecoration(
suffixIcon:
Icon(Icons.calendar_today, color: Colors.blue)),
),
),
)
],
)),
Container(
width: 5,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("End Date"),
GestureDetector(
onTap: () {
// Your second date picker logic
},
child: AbsorbPointer(
absorbing: true,
child: TextFormField(
controller: enddata,
decoration: InputDecoration(
suffixIcon:
Icon(Icons.calendar_today, color: Colors.blue)),
),
),
)
],
)),
Container(
width: 5,
),
],
)),
Select Date
TextEditingController startdata = new TextEditingController();
TextEditingController enddata = new TextEditingController();
DateTime selectedDate = DateTime.now();
var myFormat = DateFormat('yyyy-MM-dd');
Future selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: selectedDate,
lastDate: DateTime(2101),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
primaryColor: WidgetColors.buttonColor,
accentColor: WidgetColors.buttonColor,
colorScheme: ColorScheme.light(primary: WidgetColors.buttonColor),
buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary),
),
child: child,
);
},
);
if (picked != null) {
setState(() {
selectedDate = picked;
startdata = TextEditingController(text: myFormat.format(picked),);
});
} else {}
}
Try this
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Start Date", style: TextStyle(
color: Colors.blueGrey,
),),
SizedBox(height: 15.0,),
GestureDetector(
onTap: () {
// Show You Date Picker Here
},
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("YourDate e.g May 7, 2018"),
Icon(Icons.calendar_today, color: Colors.blue,),
],
),
),
)
],
),
),
SizedBox(width: 10.0,),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("End Date", style: TextStyle(
color: Colors.blueGrey,
),),
SizedBox(height: 15.0,),
GestureDetector(
onTap: () {
// Show You Date Picker Here
},
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("YourDate e.g May 8, 2018"),
Icon(Icons.calendar_today, color: Colors.blue,),
],
),
),
),
],
),
),
],
)
I have a generic TextFieldWidget class I use for all my Flutter projects, which is really useful and can answer your question.
enum TextFieldType {
Password,
Email,
Text,
Picker,
}
class TextFieldWidget extends StatefulWidget {
final TextEditingController controller;
final FocusNode focusNode;
final Key key;
final String errorText;
final String hintText;
final Color errorBorderColor;
final bool autofocus;
final bool isEnabled;
final Function onChanged;
final Function onTap;
final TextFieldType textFieldType;
final TextCapitalization textCapitalization;
final Widget suffixIcon;
TextFieldWidget({
this.controller,
this.focusNode,
this.key,
this.errorText,
this.hintText,
this.errorBorderColor,
this.autofocus = false,
this.isEnabled = true,
this.onChanged,
this.onTap,
this.textFieldType = TextFieldType.Text,
this.textCapitalization = TextCapitalization.none,
this.suffixIcon,
});
#override
State createState() => _TextFieldWidgetState();
}
class _TextFieldWidgetState extends State<TextFieldWidget> {
final double _borderSideWidth = 0.5;
bool _shouldObscureText = true;
#override
Widget build(BuildContext context) {
return TextField(
style: TextStyle(
color: !widget.isEnabled ? ThemeColors.text.tertiaryLight : null,
fontSize: ThemeFonts.size.textFieldText,
),
enabled: widget.isEnabled,
controller: this.widget.controller,
focusNode: this.widget.focusNode,
decoration: _getTextFieldDecoration(),
autofocus: this.widget.autofocus,
obscureText: _shouldTextBeObscured(),
onChanged: this.widget.onChanged,
onTap: this.widget.onTap,
keyboardType: _getKeyboardType(),
textCapitalization: this.widget.textCapitalization,
enableInteractiveSelection: this.widget.textFieldType != TextFieldType.Picker,
);
}
InputDecoration _getTextFieldDecoration() {
return InputDecoration(
suffixIcon: _getSuffixIcon(),
labelText: widget.hintText,
labelStyle: TextStyle(color: ThemeColors.text.tertiary),
errorText: widget.errorText,
errorStyle: TextStyle(
color: widget.isEnabled ? ThemeColors.text.tertiary : ThemeColors.text.tertiaryLight,
fontSize: ThemeFonts.size.textFieldPlaceholder,
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: ThemeColors.text.tertiary,
width: _borderSideWidth,
),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: ThemeColors.border.secondary,
width: _borderSideWidth,
),
),
focusedErrorBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: ThemeColors.text.tertiary,
width: _borderSideWidth,
),
),
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: this.widget.errorBorderColor ?? ThemeColors.text.tertiary,
width: _borderSideWidth,
),
),
);
}
TextInputType _getKeyboardType() {
switch (this.widget.textFieldType) {
case TextFieldType.Email:
return TextInputType.emailAddress;
default:
return TextInputType.text;
}
}
Widget _getSuffixIcon() {
switch (this.widget.textFieldType) {
case TextFieldType.Picker:
return Icon(Icons.unfold_more);
case TextFieldType.Password:
return IconButton(
icon: Icon(Icons.remove_red_eye),
color: _shouldObscureText ? ThemeColors.icon.secondaryLight : ThemeColors.icon.secondary,
onPressed: () {
setState(() {
_shouldObscureText = !_shouldObscureText;
});
},
);
case TextFieldType.Text:
return this.widget.suffixIcon != null ? this.widget.suffixIcon : null;
default:
return null;
}
}
bool _shouldTextBeObscured() {
if (widget.textFieldType == TextFieldType.Password) {
return _shouldObscureText;
}
return false;
}
}
And when you want to use it for Date picking just call it like this:
TextFieldWidget(
focusNode: _dateFocusNode,
controller: _dateTextController,
textFieldType: TextFieldType.Picker,
hintText: 'Date of birth',
onTap: () {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).requestFocus(FocusNode());
}
// Call code that opens date picker here
},
),
Keep in mind this TextField provides more options than what you need right now, but if you plan on having error handling, different UI colours for those cases, different UI for password, email and other input this will be of great help.