0

I am working on an Appwrite project for a Netflix clone. In the Signin screen, after I enter the email and password in their respective TextFields, upon closing the keyboard, the content of the email TextField gets cleared.

Gif below for reference.

enter image description here

The relevant code:

class _OnboardingScreenState extends State<OnboardingScreen> {
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  int _selectedIndex = 0;

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  Widget _renderSignIn() {
    return Container(
      padding: const EdgeInsets.fromLTRB(60, 0, 60, 0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Center(
            child: Image.asset(Assets.netflixLogo1, width: 200),
          ),
          const SizedBox(height: 60),
          TextField(
            controller: _emailController,
            autofocus: false,
            autocorrect: false,
            enableSuggestions: false,
            decoration: const InputDecoration(
              filled: true,
              fillColor: Colors.grey,
              labelText: 'Email',
              floatingLabelStyle: TextStyle(color: Colors.black),
              focusedBorder: InputBorder.none,
              border: InputBorder.none,
            ),
          ),
          Container(
            height: 0.1,
            color: Colors.black,
          ),
          TextField(
            controller: _passwordController,
            obscureText: true,
            autofocus: false,
            autocorrect: false,
            enableSuggestions: false,
            decoration: const InputDecoration(
              filled: true,
              fillColor: Colors.grey,
              labelText: 'Password',
              floatingLabelStyle: TextStyle(color: Colors.black),
              focusedBorder: InputBorder.none,
              border: InputBorder.none,
            ),
          ),
          const SizedBox(height: 20.0),
          SizedBox(
            width: double.infinity,
            child: OutlinedButton(
              style: OutlinedButton.styleFrom(
                padding: const EdgeInsets.fromLTRB(0, 10, 0, 10),
                side: const BorderSide(width: 1.0, color: Colors.grey),
              ),
              child: const Text(
                "Sign in",
                style: TextStyle(
                    color: Colors.white,
                    fontWeight: FontWeight.bold,
                    fontSize: 22.0),
              ),
              onPressed: () async {
                final api = context.read<AccountProvider>();
                final email = _emailController.text;
                final password = _passwordController.text;

                if (email.isEmpty || password.isEmpty) {
                  showDialog(
                      context: context,
                      builder: (_) => AlertDialog(
                            title: const Text('Error'),
                            content: const Text(
                                'Please enter your email and password'),
                            actions: [
                              TextButton(
                                child: const Text('OK'),
                                onPressed: () => Navigator.of(context).pop(),
                              )
                            ],
                          ));

                  return;
                }

                await api.login(email, password);
              },
            ),
          ),
          const SizedBox(height: 40.0),
          MaterialButton(
            child: const Text(
              "Don't have an account? Sign up",
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () {
              setState(() {
                _selectedIndex = 1;
              });
            },
          ),
          const SizedBox(height: 10.0),
          MaterialButton(
            child: const Text(
              "Forgot your password?",
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () {},
          ),
        ],
      ),
    );
  }

@override
  Widget build(BuildContext context) {
    final Size screenSize = MediaQuery.of(context).size;

    final current = context.watch<AccountProvider>().current;

    _emailController.text = current?.email ?? "";

    return Scaffold(
        extendBodyBehindAppBar: true,
        body: IndexedStack(
          index: _selectedIndex,
          children: [
            _renderSignIn(),
            _renderSignUp(),
          ],
        ));
  }
}

What is wrong in the code which causes the said behaviour and how to fix it?

Ayan Dasgupta
  • 304
  • 1
  • 4
  • 11
  • 1
    Problem is with line `_emailController.text = current?.email ?? "";` in your `build` method. Put there log to see when it's called. – Tomas Ivan Sep 05 '22 at 06:04
  • Take a look for reason why is `build` method called in documentation https://api.flutter.dev/flutter/widgets/State/build.html. I would bet on `After a dependency of this State object changes (e.g., an InheritedWidget referenced by the previous build changes).`. – Tomas Ivan Sep 05 '22 at 06:23

1 Answers1

1

Problem with build method. On dismiss keyboard build() method call and your current variable get empty value.

You can move this current variable in initState method.

@override
  void initState() {
    super.initState();
    final current = Provider.of(AccountProvider,listen:false).current;
    _emailController.text = current?.email ?? "";
  }
Harsh Sureja
  • 1,052
  • 1
  • 9
  • 22