-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Closed
Labels
r: solvedIssue is closed as solvedIssue is closed as solved
Description
After upgrade to new Flutter 3 My app in android version start wried behaviour .
After through inspection I noticed that when I focus on any TextFieldEdit the on-Screen KeyBoard appear and App Goes one-Step Backward. It happen only in Android. IOS is working fine .
I have tested in Android Emulator as well as real device . As soon I focused on TextFieldEdit System-Keyboard appear and App goes 1 step backward.
Please let me know to fix the issue.
Steps to Reproduce
- Execute
flutter runon the code sample - ...
- ...
Expected results:
Actual results:
Code sample
import 'dart:convert';
import 'package:flutter/material.dart';
//import: import_of_legacy_library_into_null_safe
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_sms/flutter_sms.dart';
//import 'package:mypaaa/blocs/attachments/attachment_page.dart';
import 'package:mypaaa/blocs/journal/journal.dart';
//import 'package:mypaaa/blocs/appointment/appointment.dart';
//import 'package:mypaaa/blocs/appointment/bloc.dart';
import 'package:mypaaa/blocs/appointment/add/bloc.dart';
import 'package:mypaaa/blocs/productblog/address.dart';
import 'package:mypaaa/blocs/productblog/jconfig.dart';
import 'package:mypaaa/blocs/profile/QRCode/bloc.dart';
import 'package:mypaaa/serviceLocator.dart';
import 'package:mypaaa/utils/allTranslation.dart';
import 'package:mypaaa/themes/themes.dart';
import 'package:mypaaa/utils/config.dart';
import 'package:mypaaa/utils/dropdownvalues.dart';
import 'package:mypaaa/utils/helper.dart';
import 'package:mypaaa/widgets/form-inputs/FullScreenInfo.dart';
import 'package:mypaaa/widgets/form-inputs/Loading.dart';
import 'package:mypaaa/utils/country_codes.dart' as countryList;
//import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
class AddAppointmentForm extends StatefulWidget {
final Journal journal;
final int role;
final Appointment? appointment;
AddAppointmentForm(this.journal,
[this.role = roles.readonly_linkonly, this.appointment]);
@override
State<AddAppointmentForm> createState() => _AddAppointmentFormState();
}
class _AddAppointmentFormState extends State<AddAppointmentForm> {
final _enterBy = TextEditingController();
AddAppointmentBloc bloc = locator.get<AddAppointmentBloc>();
//Helper helper = Helper();
final _dd = TextEditingController();
final _mm = TextEditingController();
final _yyyy = TextEditingController();
final _contactNumber = TextEditingController();
final _name = TextEditingController();
final _date = TextEditingController();
final _age = TextEditingController();
final _yob = TextEditingController();
String myName = '', myPhone = '';
final DateTime selectedDate = DateTime.now();
DateTime lastDate = DateTime.now();
DateTime pickedDate = DateTime.now();
AppointmentType appType = AppointmentType(0, 'none');
List<AppointmentType> appointmentTypes = [];
Gender gender = Gender(0, 'male');
List<Gender> genders = [];
Map<String, dynamic> config = {};
Helper helper = Helper();
Map<String, dynamic> _countryMapMap = {};
@override
void initState() {
super.initState();
AppointmentTypes aTypes = AppointmentTypes();
if (widget.journal.type == journalTypes.appoitment) {
appointmentTypes = aTypes.list();
} else if (widget.journal.type == journalTypes.videoConsult ||
widget.journal.type == journalTypes.videoDoc) {
appointmentTypes = aTypes.listVideo();
} else if (widget.journal.type == journalTypes.queue) {
appointmentTypes = aTypes.listVideo();
}
appType = appointmentTypes[0];
genders = Genders().list();
gender = genders[0];
_loadData();
}
_loadData() async {
Map<String, String> user = await UserRepository().getRegistrationPhone();
Map<String, dynamic> countryMapMap =
countryList.getCountryCodes(user["country"]!.toUpperCase());
config = json.decode(widget.journal.config);
int advanceBooking =
helper.castInt(config['max']) > 0 ? helper.castInt(config['max']) : 2;
lastDate = selectedDate.add(new Duration(days: advanceBooking));
setState(() {
_countryMapMap = countryMapMap;
_enterBy.text = user['phone'] ?? '';
if (widget.role == roles.readonly_linkonly) {
myName = user['name'] ?? '';
myPhone = user['phone'] ?? '';
_name.text = myName;
_contactNumber.text = myPhone;
} else {
_contactNumber.text = _countryMapMap["phoneCode"];
appType = appointmentTypes[appointmentTypes.length - 1];
}
_date.text = selectedDate.day.toString() +
"/" +
selectedDate.month.toString() +
"/" +
selectedDate.year.toString();
if (widget.appointment != null) {
myName = widget.appointment!.name;
myPhone = widget.appointment!.contactNumber;
_name.text = widget.appointment!.name;
_contactNumber.text = widget.appointment!.contactNumber;
_yob.text = widget.appointment!.yob.toString();
_age.text = (widget.appointment!.age).toString();
gender = genders.firstWhere(
(row) => (row.id == widget.appointment!.gender),
orElse: () => genders[0]);
}
});
}
/*
@override
void didChangeDependencies() {
//we don't have to close or unsubscribe SB
print("didChangeDependencies --- YES");
//bloc = BlocProvider.of<AddAppointmentBloc>(context, listen: false);
super.didChangeDependencies();
}
*/
_onConfirmButtonPressed2(AddAppointmentBloc _bloc) {
if (!helper.minimumLength(_contactNumber.text.trim(), 8)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(allTranslations.text('contact_number_is_required')),
backgroundColor: Colors.red,
),
);
return;
}
if (!helper.minimumLength(_name.text.trim(), 4)) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(allTranslations.text('contact_name_is_required')),
backgroundColor: Colors.red,
),
);
return;
}
if (helper.castInt(_yob.text.trim()) < DateTime.now().year - 90 ||
helper.castInt(_yob.text.trim()) > DateTime.now().year) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(allTranslations.text('wrong_yob')),
backgroundColor: Colors.red,
),
);
return;
}
Appointment appointment = Appointment.empty();
appointment.appointmentType = appType.id;
appointment.name = _name.text;
appointment.contactNumber = _contactNumber.text;
appointment.dd = pickedDate.day;
appointment.mm = pickedDate.month;
appointment.yyyy = pickedDate.year;
appointment.yob = helper.castInt(_yob.text);
appointment.gender = gender.id;
appointment.journalId = widget.journal.id;
appointment.enterBy = _enterBy.text;
//if(bloc){
if (widget.appointment == null) {
_bloc.add(
AddAppointment(appointment: appointment, journal: widget.journal),
);
} else {
appointment.id = widget.appointment!.id;
appointment.queue = widget.appointment!.queue;
_bloc.add(
UpdateAppointment(appointment: appointment, journal: widget.journal),
);
}
//}
}
//final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext contextFrm) {
//bloc = BlocProvider.of<AddAppointmentBloc>(contextFrm);
_save() {
_onConfirmButtonPressed2(bloc);
}
_onRetryButtonPressed() {
// print("****** * * * ** * * * ");
bloc.add(
ReloadFormAppointment(),
);
}
_onRetryButtonPressed2() {
bloc.add(
ReloadFormAppointment(),
);
}
return BlocListener(
bloc: bloc,
listener: (contextFrm, state) {
if (state is AddAppointmentSuccess) {
ScaffoldMessenger.of(contextFrm).showSnackBar(
SnackBar(
content: Text(allTranslations.text("success")),
backgroundColor: Colors.green,
),
);
} else if (state is AddAppointmentError) {
ScaffoldMessenger.of(contextFrm).showSnackBar(
SnackBar(
content: Text(allTranslations.text(state.error)),
backgroundColor: Colors.red,
),
);
}
},
child: BlocBuilder(
bloc: bloc,
builder: (contextFrm, state) {
if (state is AddAppointmentInitial) {
// print(state);
// return KeyboardVisibilityBuilder(
// builder: (contextFrm, isKeyboardVisible) {
return Form(
child: Padding(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
if (widget.role == roles.readonly_linkonly)
Row(children: <Widget>[
Icon(Icons.subject, size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(
allTranslations.text('appointment_for'),
style: subTitleStyle)),
Expanded(
flex: 6,
child: DropdownButton<AppointmentType>(
value: appType,
//isDense: true,
isExpanded: true,
onChanged: (AppointmentType? newValue) {
setState(() {
appType = newValue == null
? appointmentTypes[0]
: newValue;
int role =
newValue == null ? 1 : newValue.role;
if (role == 0) {
_name.text =
(_name.text.trim() == myName)
? ""
: _name.text;
_contactNumber.text =
(_contactNumber.text.trim() ==
myPhone)
? _countryMapMap["phoneCode"]
: _contactNumber.text;
} else if (role == 1) {
_name.text = myName;
_contactNumber.text = myPhone;
} else if (role == 2) {
_name.text =
(_name.text.trim() == myName)
? ""
: _name.text;
} else if (role == 3) {
_name.text =
(_name.text.trim() == myName)
? ""
: _name.text;
_contactNumber.text =
(_contactNumber.text.trim() ==
myPhone)
? ""
: _contactNumber.text;
} else {
_contactNumber.text =
_countryMapMap["phoneCode"];
}
//_particular.text = newValue.name;
// state.didChange(newValue);
});
},
items: appointmentTypes
.map((AppointmentType value) {
return DropdownMenuItem<AppointmentType>(
value: value,
child: Text(
allTranslations.text(value.name)),
);
}).toList(),
))
]),
if (widget.appointment == null)
Row(children: <Widget>[
Icon(Icons.date_range,
size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(
allTranslations.text('date'),
style: TextStyle(
color: Colors.grey.shade900,
fontWeight: FontWeight.bold),
)),
Expanded(
flex: 6,
child: TextFormField(
onChanged: (term) {},
readOnly: true,
keyboardType: TextInputType.text,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
Icons.calendar_today_outlined,
color: Colors.blue,
),
onPressed: () async {
final DateTime picked =
await showDatePicker(
context: context,
initialDate:
selectedDate, // Refer step 1
firstDate: selectedDate,
lastDate: lastDate,
) ??
DateTime.now();
if (picked != selectedDate)
setState(() {
pickedDate = picked;
_date.text =
picked.day.toString() +
"/" +
picked.month.toString() +
"/" +
picked.year.toString();
});
},
),
labelText: allTranslations.text('date')),
controller: _date,
))
])
else
Row(children: [
Icon(Icons.date_range,
size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(
allTranslations.text('date'),
style: TextStyle(
color: Colors.grey.shade900,
fontWeight: FontWeight.bold),
)),
Expanded(
flex: 6,
child: Text(
"${widget.appointment!.dd}/${widget.appointment!.mm}/${widget.appointment!.yyyy} #:${widget.appointment!.queue}",
style: subTitleStyle,
),
)
]),
Row(children: <Widget>[
Icon(Icons.subject, size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(allTranslations.text('name'),
style: subTitleStyle)),
Expanded(
flex: 6,
child: TextFormField(
onChanged: (term) {},
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: allTranslations.text('name')),
controller: _name,
))
]),
Row(children: <Widget>[
Icon(Icons.money, size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(allTranslations.text('contactNumber'),
style: subTitleStyle)),
Expanded(
flex: 6,
child: TextFormField(
onChanged: (term) {},
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText:
allTranslations.text('contactNumber')),
controller: _contactNumber,
))
]),
Row(children: <Widget>[
Icon(Icons.repeat_rounded,
size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(allTranslations.text('gender'),
style: subTitleStyle)),
Expanded(
flex: 6,
child: DropdownButton<Gender>(
value: gender,
//isDense: true,
isExpanded: true,
onChanged: (Gender? newValue) {
setState(() {
//assessHed.asAnimal = newValue;
gender = newValue ?? genders[0];
// state.didChange(newValue);
});
},
items: genders.map((Gender value) {
return DropdownMenuItem<Gender>(
value: value,
child:
Text(allTranslations.text(value.name)),
);
}).toList(),
))
]),
Row(children: <Widget>[
Icon(Icons.money, size: 24, color: formIconColor),
Expanded(
flex: 4,
child: Text(allTranslations.text('age'),
style: subTitleStyle)),
Expanded(
flex: 3,
child: TextFormField(
onChanged: (term) {
int year = selectedDate.year;
int yob = helper.castInt(term);
setState(() {
_age.text = (year - yob).toString();
});
},
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: allTranslations.text('yob')),
controller: _yob,
)),
Expanded(
flex: 3,
child: TextFormField(
onChanged: (term) {
int year = selectedDate.year;
int age = helper.castInt(term);
setState(() {
_yob.text = (year - age).toString();
});
},
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: allTranslations.text('age')),
controller: _age,
))
]),
Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0, horizontal: 5.0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: mainTheme.buttonColor),
onPressed: _save,
child: Text(
allTranslations.text("book_appoitment"),
textAlign: TextAlign.center,
)),
),
],
)));
// });
} else if (state is AddAppointmentSuccess) {
return FullScreenInfo(
sendSMS: true,
onSMS: () async {
JConfig jConfig =
JConfig.fromMap(jsonDecode(widget.journal.config));
Address address =
Address.fromMap(jsonDecode(widget.journal.address));
String smsMain = helper.apptSMS(
state.appt,
widget.journal.title,
jConfig,
address.houseUnitNo +
" " +
address.address +
"," +
address.city);
await _sendSMS(context, smsMain, state.appt.contactNumber);
},
closeWindow: true,
onClose: () {
var nav = Navigator.of(context);
nav.pop();
// nav.pop();
},
showSerial: true,
infoSerial: allTranslations.text("serial_no") +
" : " +
state.appt.queue.toString(),
info: allTranslations.text("please_check_mynotes"),
);
} else if (state is AddAppointmentLoading) {
return Loading(withText: true);
} else if (state is AddAppointmentError) {
return FullScreenInfo(
info: allTranslations.text(state.error),
errorType: true,
onRetry: () {
bloc.add(
ReloadFormAppointment(),
);
});
} else {
return Text('');
}
},
),
);
}
Future<void> _sendSMS(
BuildContext context, String message, String recipients) async {
try {
await sendSMS(message: message, recipients: [recipients]);
//setState(() => _message = _result);
} catch (error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(error.toString()),
backgroundColor: Colors.red,
),
);
}
}
@override
void dispose() {
_dd.dispose();
_mm.dispose();
_yyyy.dispose();
_contactNumber.dispose();
_name.dispose();
_date.dispose();
_yob.dispose();
_age.dispose();
super.dispose();
}
}Logs
Bug-Android.mov
Metadata
Metadata
Assignees
Labels
r: solvedIssue is closed as solvedIssue is closed as solved
