Skip to content

Android only : When focus on TextFieldEdit the Onscreen-keyboard appear and app goes to one step backward  #110745

@excode

Description

@excode

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.

Screenshot 2022-09-01 at 11 37 24 AM

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. ...
  3. ...

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

No one assigned

    Labels

    r: solvedIssue is closed as solved

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions