When I press on the textformfield to input text keyboard shortly appears and disappears quickly then a circular progress indicator is on a black screen is shown like for 1 second and then return to the base page this project have not been touched in 4 months it was working before. I am sure I did copy the whole code into another new project and the same issue occurs my code has no errors and the code works find in any web browser this problem is only in the home page textfield in other pages work normally
I have tried copying the code file by file into another project from scratch didn't work.
I have tried isolating neighbor widgets to the textfield simplifying the ui just commenting the other near widget also didn't work.
I have tried to add final and static to the from key (even though my global key is not in the build method).
I removed the screen util package from my project didn't work
Nothing worked really did not expect anything to happen I have asked bing and chatgpt which pointed to a performance issues don't know I am not an experienced flutter developer would need to know how to use performance toold in vs code or Android Studio before diving into this I did get logs like missed frame timeout anf forced finish but don't know if the keyboard appearing and disappearing quickly is the cause for such rendering issues or the opposite.
This is the code of the leave request container.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../../../constants/breakpoints.dart';
import '../../../constants/leave_data.dart';
import '../../../services/leave_request_api.dart';
import '../../../util/app_text_style.dart';
import '../../../util/size_config.dart';
class LeaveRequestContainer extends StatefulWidget {
const LeaveRequestContainer({super.key});
@override
State<LeaveRequestContainer> createState() => _LeaveRequestContainerState();
}
class _LeaveRequestContainerState extends State<LeaveRequestContainer> {
User? user = FirebaseAuth.instance.currentUser;
String? uid;
GlobalKey<FormState> form = GlobalKey<FormState>();
TextEditingController leavetype = TextEditingController();
String? selectedOption;
String? selectedOptionLeave;
TextEditingController comment = TextEditingController();
late DateTimeRange? picked;
late DateTime? selectedDate;
bool daterange = false;
late DateTime? startdate;
late DateTime? enddate;
late Map<String, dynamic> data;
DateTime? day;
@override
void dispose() {
// TODO: implement dispose
super.dispose();
leavetype.dispose();
comment.dispose();
}
@override
void initState() {
// TODO: implement initState
super.initState();
uid = user!.uid;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
child: SizedBox(
width: SizeConfig.screenWidth > tabletBreakpointwidth
? SizeConfig.blockSizeHorizontal * 35
: SizeConfig.screenWidth * 0.95,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
elevation: 7,
margin: const EdgeInsets.all(10),
child: Column(
children: [
Stack(
children: [
ClipRRect(
borderRadius: const BorderRadius.only(
topRight: Radius.circular(15),
topLeft: Radius.circular(15)),
child: Image.asset(
'images/leaveMan.jpg',
height: SizeConfig.blockSizeVertical * 31,
width: double.infinity,
fit: BoxFit.cover,
),
),
Container(
height: SizeConfig.blockSizeVertical * 31,
alignment: Alignment.bottomRight,
padding: const EdgeInsets.symmetric(
vertical: 10, horizontal: 10),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.1),
Colors.black.withOpacity(0.8)
],
stops: const [
0.4,
1
])),
)
],
),
Form(
key: form,
child: Padding(
padding: const EdgeInsets.all(6.0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
//text and icoon
LeaveTypeRowDesign(),
ListOptionsLeave(
selectedOptionLeave: selectedOptionLeave,
logic: (value) {
setState(() {
selectedOptionLeave = value;
});
},
),
//text and icon
DurationRowDesign(),
ListOptionDuration(
selectedOption: selectedOption,
logic: (value) {
setState(() {
selectedOption = value;
if (selectedOption == durationOptions[1]) {
daterange = true;
} else {
daterange = false;
}
});
},
),
//Leave Date Range
Row(
children: [
Padding(
padding: const EdgeInsets.only(left: 4),
child: Icon(daterange
? Icons.date_range
: Icons.calendar_month)),
InkWell(
onTap: () async {
if (selectedOption == durationOptions[1]) {
picked = (await showDateRangePicker(
context: context,
firstDate:
DateTime(DateTime.now().year, 1, 1),
lastDate: DateTime(
DateTime.now().year, 12, 31),
builder: (context, child) {
return Theme(
data: ThemeData(
colorScheme:
const ColorScheme.light()
.copyWith(
background: Colors
.yellow)),
child: child!);
},
));
if (picked != null) {
startdate = picked!.start;
enddate = picked!.end;
//Retrieve the values here and do the necessary logic.
}
} else {
selectedDate = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate:
DateTime(DateTime.now().year, 1, 1),
lastDate: DateTime(
DateTime.now().year, 12, 31),
builder: (context, child) {
return Theme(
data: ThemeData(
colorScheme:
const ColorScheme.light()
.copyWith(
background: Colors
.yellow)),
child: child!);
},
);
if (selectedDate != null) {
day = selectedDate;
//Retrieve the values here and do the necessary logic
}
}
},
child: smalTitle(
title: daterange ? 'Range' : 'Day'))
],
),
Divider(
color: Colors.grey.withOpacity(0.6),
indent: 10,
thickness: 1,
),
//icon and text
ReasonRowDesign(),
ReasonField(comment: comment),
Padding(
padding: const EdgeInsets.only(left: 3, top: 2),
child: Text(
'Leave Balance',
style: AppTextStyles.orangeText,
),
),
const Divider(
thickness: 4,
),
const Padding(
padding:
EdgeInsets.only(left: 3, top: 2, bottom: 6),
child: Text(
'10 Days',
style: TextStyle(fontWeight: FontWeight.bold),
),
),
const SizedBox(
height: 5,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 3),
child: ElevatedButton.icon(
style: const ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(Colors.black)),
onPressed: () async {
//Gather All your Values Here
if (form.currentState!.validate()) {
print(uid);
String reason = comment.text.trim();
data = {
'uid': uid,
'durationName': selectedOption,
'statusName': 'Pending',
'leavePolicyName': selectedOptionLeave,
'reason': reason,
'startDate': daterange
? startdate.toString()
: null,
'endDate':
daterange ? enddate.toString() : null,
'day': daterange ? null : day.toString()
};
FutureBuilder(
future: addLeaveRequest(data),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.waiting) {
// Show a loading indicator while waiting for the response
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
// Show an error message if an error occurs
return Text(
'Error: ${snapshot.error}');
} else {
return const AlertDialog(
title: Text(
'Leave Request Submitted Successfuly'),
);
}
},
);
}
},
icon: const Icon(Icons.send),
label: const Text('Book Time Off')),
),
const Padding(padding: EdgeInsets.all(4))
],
),
),
),
),
],
),
),
),
),
);
}
//Alt The Necessary Method Here
}
class ReasonRowDesign extends StatelessWidget {
const ReasonRowDesign({
super.key,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
const Padding(
padding: EdgeInsets.only(left: 4),
child: Icon(Icons.label),
),
smalTitle(title: 'Reason'),
],
);
}
}
class DurationRowDesign extends StatelessWidget {
const DurationRowDesign({
super.key,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
const Padding(
padding: EdgeInsets.only(left: 4), child: Icon(Icons.timer)),
smalTitle(title: 'Duration'),
],
);
}
}
class LeaveTypeRowDesign extends StatelessWidget {
const LeaveTypeRowDesign({
super.key,
});
@override
Widget build(BuildContext context) {
return Row(
children: [
const Padding(
padding: EdgeInsets.only(left: 4),
child: Icon(Icons.time_to_leave_sharp)),
smalTitle(title: 'Leave Type'),
],
);
}
}
class ReasonField extends StatelessWidget {
const ReasonField({
super.key,
required this.comment,
});
final TextEditingController comment;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.withOpacity(0.6), width: 0),
borderRadius: BorderRadius.circular(0),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: TextFormField(
maxLines: null,
validator: (value) {
if (value!.isEmpty) {
return 'Please cite a reason';
} else if (value.length <= 20) {
return ' Text must be larger than 20 characters ';
}
return null;
},
style: const TextStyle(fontSize: 17.6),
controller: comment,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Reason',
hintStyle: TextStyle(
fontSize: 17.6, color: Colors.black.withOpacity(0.8))),
),
),
),
);
}
}
class smalTitle extends StatelessWidget {
const smalTitle({
super.key,
required this.title,
});
final String title;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
child: Text(
title,
style: const TextStyle(fontSize: 12.0, fontWeight: FontWeight.w900),
),
);
}
}
class FormField extends StatelessWidget {
const FormField({
super.key,
required this.Controller,
required this.hinttext,
});
final TextEditingController Controller;
final String hinttext;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(4),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: TextFormField(
style: const TextStyle(fontSize: 22.6),
controller: Controller,
decoration: InputDecoration(
border: InputBorder.none,
hintText: hinttext,
hintStyle: const TextStyle(fontSize: 22.6)),
),
),
),
);
}
}
class ListOptionDuration extends StatefulWidget {
final String? selectedOption;
final void Function(String?)? logic;
const ListOptionDuration(
{super.key, required this.selectedOption, required this.logic});
@override
State<ListOptionDuration> createState() => _ListOptionDurationState();
}
class _ListOptionDurationState extends State<ListOptionDuration> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: DropdownButton(
elevation: 0,
isDense: true,
items: durationOptions
.map((item) => DropdownMenuItem(value: item, child: Text(item)))
.toList(),
isExpanded: true,
onChanged: widget.logic,
iconEnabledColor: Colors.blue[900],
value: widget.selectedOption,
),
);
}
}
class ListOptionsLeave extends StatefulWidget {
final String? selectedOptionLeave;
final void Function(String?)? logic;
const ListOptionsLeave(
{super.key, required this.selectedOptionLeave, required this.logic});
@override
State<ListOptionsLeave> createState() => _ListOptionsLeaveState();
}
class _ListOptionsLeaveState extends State<ListOptionsLeave> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: DropdownButton(
elevation: 0,
isDense: true,
iconEnabledColor: Colors.blue[900],
items: leaveTypeOptions
.map((item) => DropdownMenuItem(value: item, child: Text(item)))
.toList(),
isExpanded: true,
onChanged: widget.logic,
value: widget.selectedOptionLeave,
),
);
}
}