Abir Ahsan
Abir Ahsan

Reputation: 3049

Flutter : TextFormField real device keyboard problem ( Error: Composing region changed by the framework. Restarting the input method )

I implemented a Form page with getx state management. Everything is fine when I test it on simulator. But When I used real device for test, I faced a problem. Actually Here is a one page for two type works.

  1. For New Users
  2. Update User

For new user, form textfield controller initial value is null. And it's always work fine until use unChanged function. By the way, I Don't need onChanged when I using Controller

For Update User, I initialled a value on Textformfield controller inside build. This Textformfield work fine on simulator. But I run it real device, and click on TextFormField, my cursor move to first automatically . And when I unfocused TextformField after typing value, my last value is vanished. And it's show me this type error:

W/IInputConnectionWrapper(30962): getCursorCapsMode on inactive InputConnection
W/IInputConnectionWrapper(30962): getExtractedText on inactive InputConnection
I/TextInputPlugin(30962): Composing region changed by the framework. Restarting the input method.
W/IInputConnectionWrapper(30962): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(30962): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(30962): getTextBeforeCursor on inactive InputConnection

> Here is my ControllerPage

class UserFormController extends GetxController {
  RxBool isNewUser = false.obs;

  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  late TextEditingController nameCtrl, jobCtrl;

  @override
  void onInit() {
    nameCtrl = TextEditingController();
    jobCtrl = TextEditingController();
    super.onInit();
  }

  @override
  void onClose() {
    nameCtrl.dispose();
    jobCtrl.dispose();
    super.onClose();
  }
}

> And here is my view page

class UserFormScreen extends GetView<UserFormController> {
  final bool isNewUser;
  final Data? user;
  const UserFormScreen({Key? key, required this.isNewUser, this.user})
      : super(key: key);
  @override
  Widget build(BuildContext context) {
    double _width = MediaQuery.of(context).size.width;
    double _height = MediaQuery.of(context).size.height;
    final UserFormController formCtrl = Get.put(UserFormController());
    if (!isNewUser) {
      formCtrl.nameCtrl.text = "${user!.firstName} ${user!.lastName}";
    }
    return Scaffold(
      appBar: AppBar(
        title: Text(isNewUser ? "Create New User" : "Update User"),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTap: () {
          FocusManager.instance.primaryFocus?.unfocus();
        },
        child: SizedBox(
          height: _height,
          width: _width,
          child: Form(
            key: formCtrl.formKey,
            child: SingleChildScrollView(
              child: Column(
                children: [
                  const SizedBox(
                    height: 40,
                  ),
                  CustomTextField(
                    labelText: "Name",
                    hintText: "ex. Robert",
                    controller: formCtrl.nameCtrl,
                    validator: (value) {
                      return formCtrl.validateName(value!);
                    },
                    onChanged: (val) {
                      formCtrl.nameCtrl.text = val;
                      formCtrl.nameCtrl.selection = TextSelection.fromPosition(
                          TextPosition(offset: formCtrl.nameCtrl.text.length));
                    },
                  ),
                  CustomTextField(
                    labelText: "Job",
                    hintText: "ex. Manager",
                    controller: formCtrl.jobCtrl,
                    validator: (value) {},
                  ),
                  ElevatedButton(
                    onPressed: () {
                      FocusManager.instance.primaryFocus?.unfocus();

                      if (validateAndSave(formCtrl.formKey)) {
                        if (isNewUser) {
                          //create new

                          formCtrl.createNewUser();
                        } else {
                          //update
                          formCtrl.updateUser(user!.id);
                        }
                      }
                    },
                    child: Text(
                      isNewUser ? "Create" : "Update",
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Upvotes: 1

Views: 1937

Answers (3)

Alex Lovsky
Alex Lovsky

Reputation: 50

Your problem is:

formCtrl.nameCtrl.text = val;

No need to set controller.text inside onChanged

Upvotes: 0

Senior developer
Senior developer

Reputation: 29

I solved this error this way:

  1. run flutter clean
  2. run flutter pub get
  3. uninstall the app

Upvotes: 1

Behzod Faiziev
Behzod Faiziev

Reputation: 445

I faced the same problem. In my situation I wanted from one textField focus to another textfield.

Even though in initialiazed focusNode for each fields, I had this error: Composing region changed by the framework. Restarting the input method.

The mistake I made was that I didn't paste focusNode in my customTextFormField, so that textFormFields were not set by their focuses

If you still have any issues, you can ask me more!

Upvotes: 1

Related Questions