'Navigation from hookwidget screen to a nother hookwidget screen via button tap not working

I have a landing screen from which I tried to access authentication screens via respective buttons. The landing screen and the authentication screen extend HookWidget and HookConsumerWidget. I have these 2 problems that have left me frustrated and need your help.

  1. The images are supposed to animate linearly and continuously. The animation is not working as I get only a static image that changes only upon hot reload.

  2. Clicking on say the Login button to access the AuthScreen screen, returns error: "Hooks can only be called from the build method of a widget that mix-in.

LandingScreen:

class LandingScreen extends HookWidget {
  LandingScreen({Key? key}) : super(key: key);

  static const routeName = 'landingScreen';

  final List<String> _images = [
    'assets/images/shopping1.jpeg',
    'assets/images/shopping2.jpeg',
  ];

  @override
  Widget build(BuildContext context) {
    late Animation _animation;
    final _animationController = useAnimationController(
      duration: const Duration(seconds: 2),
    );

    useEffect(() {
      _images.shuffle();
      final _animationController = useAnimationController(
        duration: const Duration(seconds: 20),
      );

      _animation =
          CurvedAnimation(parent: _animationController, curve: Curves.linear)
            ..addListener(() {
              _animationController.value;
            })
            ..addStatusListener((animationStatus) {
              if (animationStatus == AnimationStatus.completed) {
                _animationController.reset();
                _animationController.forward();
              }
            });

      _animationController.forward();
    }, const []);


    return Scaffold(
      body: Stack(
        children: [
          SizedBox(
            width: double.infinity,
            height: double.infinity,
            child: Image.asset(
              _images[0],
              // 'assets/images/shopping2.jpeg',
              fit: BoxFit.cover,
              // alignment: FractionalOffset(_animation.value, 0),
            ),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: const [
              SizedBox(
                height: 50,
              ),
              Center(
                child: Text(
                  'Welcome to',
                  style: TextStyle(fontSize: 30, color: Colors.white),
                ),
              ),
              Center(
                child: Text(
                  'Eleganza Mall',
                  style: TextStyle(
                    fontSize: 50,
                    color: Colors.white,
                    // color: Color(0XFF660000),
                  ),
                ),
              ),
            ],
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  children: [
                    Expanded(
                      child: MyButton(
                        text: 'Login',
                        txtColor: Colors.white,
                        txtSize: 20,
                        bgColor: Colors.deepPurple,
                        onTap: () {
                          Navigator.pushReplacementNamed(
                              context, AuthScreen.routeName,
                              arguments: 'login');
                        },
                      ),
                    ),
                    const SizedBox(
                      width: 10,
                    ),
                    Expanded(
                      child: MyButton(
                        text: 'Sign Up',
                        txtColor: Colors.white,
                        txtSize: 20,
                        bgColor: Colors.deepPurple,
                        onTap: () {
                          Navigator.pushReplacementNamed(
                              context, AuthScreen.routeName,
                              arguments: 'register');
                        },
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 20,
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  children: [
                    Expanded(
                      child: MyButton(
                        text: 'Google Sign In',
                        txtColor: Colors.white,
                        txtSize: 20,
                        bgColor: Colors.deepPurple,
                        onTap: () {},
                      ),
                    ),
                    const SizedBox(
                      width: 10,
                    ),
                    Expanded(
                      child: MyButton(
                        text: 'Sign in as Guest',
                        txtColor: Colors.white,
                        txtSize: 20,
                        bgColor: Colors.deepPurple,
                        onTap: () {},
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 20,
              ),
            ],
          ),
        ],
      ),
    );
  }
}

AuthScreen

@override
  Widget build(BuildContext context, WidgetRef ref) {
    final authMode = ModalRoute.of(context)?.settings.arguments as String;

    switch (authMode) {
      case 'login':
        _authMode.value = AuthMode.login;
        break;
      case 'register':
        _authMode.value = AuthMode.register;
        break;
      case 'guest':
        _authMode.value = AuthMode.guest;
        break;
      case 'google':
        _authMode.value = AuthMode.google;
        break;
    }
    return Scaffold(
      body: Stack(
        children: [
          RotatedBox(
            quarterTurns: 2,
            child: WaveWidget(
              config: CustomConfig(
                durations: [35000, 11000, 10800, 6000],
                colors: [
                  Colors.orangeAccent,
                  Colors.tealAccent,
                  Colors.pinkAccent,
                  Colors.deepPurpleAccent,
                ],
                heightPercentages: [0.01, 0.02, 0.03, 0.1],
                blur: const MaskFilter.blur(BlurStyle.solid, 0),
              ),
              heightPercentange: 0.2,
              size: const Size(double.infinity, double.infinity),
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Form(
              key: _formKey,
              child: SingleChildScrollView(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    const SizedBox(
                      height: 80,
                    ),
                    Center(
                      child: _authMode.value == AuthMode.login
                          ? const Text(
                              'Access Your Account',
                              style: TextStyle(
                                fontSize: 25,
                              ),
                            )
                          : Row(
                              children: [
                                InkWell(
                                  onTap: () => _showPicker(context),
                                  child: CircleAvatar(
                                    radius: 50,
                                    backgroundImage: _imageFile.value == null
                                        ? null
                                        : FileImage(
                                            File(_imageFile.value!.path),
                                          ),
                                    child: _imageFile.value == null
                                        ? const Icon(
                                            Icons.camera,
                                            // Icons.add_photo_alternate,
                                            size: 30,
                                            color: Colors.white,
                                          )
                                        : null,
                                  ),
                                ),
                                const SizedBox(
                                  width: 15,
                                ),
                                const Text(
                                  'Create an Account',
                                  style: TextStyle(
                                    fontSize: 25,
                                  ),
                                ),
                              ],
                            ),
                    ),
                    const SizedBox(
                      height: 30,
                    ),
                    if (_authMode.value == AuthMode.register)
                      TextFormField(
                        onEditingComplete: () => FocusScope.of(context)
                            .requestFocus(_phoneFocusScope),
                        decoration: kTextInputDecoration.copyWith(
                          labelText: 'Fullname',
                          filled: true,
                          fillColor: Theme.of(context).cardColor,
                          prefixIcon: const Icon(
                            Icons.account_circle,
                            size: 30,
                          ),
                          contentPadding: const EdgeInsets.all(10),
                        ),
                        keyboardType: TextInputType.name,
                        textInputAction: TextInputAction.next,
                        onFieldSubmitted: (_) {
                          FocusScope.of(context).requestFocus(_phoneFocusScope);
                        },
                        validator: (value) {
                          if (value!.isEmpty || isNumeric(value)) {
                            return 'Only alphabet characters and cannot be blank';
                          }
                          return null;
                        },
                        onSaved: (value) {
                          name = value!;
                        },
                      ),
                    const SizedBox(
                      height: 10,
                    ),
                    if (_authMode.value == AuthMode.register)
                      TextFormField(
                        focusNode: _phoneFocusScope,
                        decoration: kTextInputDecoration.copyWith(
                          labelText: 'Phone Number',
                          filled: true,
                          fillColor: Theme.of(context).cardColor,
                          prefixIcon: const Icon(
                            Icons.phone,
                            size: 30,
                          ),
                          contentPadding: const EdgeInsets.all(10),
                        ),
                        keyboardType: TextInputType.phone,
                        textInputAction: TextInputAction.next,
                        onEditingComplete: () => FocusScope.of(context)
                            .requestFocus(_emailFocuScope),
                        onFieldSubmitted: (_) {
                          FocusScope.of(context).requestFocus(_emailFocuScope);
                        },
                        validator: (value) {
                          if (value!.isEmpty || value.trim().length < 10) {
                            return 'Cannot be blank or shorter than 10 chars';
                          }
                          return null;
                        },
                        onSaved: (value) {
                          phone = value!;
                        },
                      ),
                    const SizedBox(
                      height: 10,
                    ),
                    TextFormField(
                      key: const ValueKey('email'),
                      focusNode: _emailFocuScope,
                      validator: (value) {
                        if (!isEmail(value!)) {
                          return 'Please enter a valid email';
                        }
                        return null;
                      },
                      onSaved: (value) {
                        // _authData['email'] = value!;
                        email = value!;
                      },
                      textInputAction: TextInputAction.next,
                      onEditingComplete: () => FocusScope.of(context)
                          .requestFocus(_passwordFocusScope),
                      onFieldSubmitted: (_) {
                        FocusScope.of(context)
                            .requestFocus(_passwordFocusScope);
                      },
                      decoration: kTextInputDecoration.copyWith(
                        labelText: 'Email',
                        filled: true,
                        fillColor: Theme.of(context).cardColor,
                        prefixIcon: const Icon(
                          Icons.email,
                          size: 30,
                        ),
                        contentPadding: const EdgeInsets.all(10),
                      ),
                      keyboardType: TextInputType.emailAddress,
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    TextFormField(
                      controller: _passwordController,
                      focusNode: _passwordFocusScope,
                      // onEditingComplete: _submit,
                      onEditingComplete: () => FocusScope.of(context)
                          .requestFocus(_confirmFocusScope),
                      obscureText: _isVisible.value,
                      key: const ValueKey('password'),
                      validator: (value) {
                        if (value!.isEmpty || value.length < 8) {
                          return 'Password cannot be empty and must be at least 8 chars!';
                        }
                        return null;
                      },
                      onSaved: (value) {
                        // _authData['password'] = value!;
                        password = value!;
                      },
                      textInputAction: TextInputAction.next,
                      onFieldSubmitted: (_) {
                        FocusScope.of(context).requestFocus(_confirmFocusScope);
                      },
                      decoration: kTextInputDecoration.copyWith(
                        labelText: 'Password',
                        filled: true,
                        fillColor: Theme.of(context).cardColor,
                        prefixIcon: const Icon(
                          Icons.lock,
                          size: 30,
                        ),
                        suffixIcon: IconButton(
                          icon: _isVisible.value
                              ? const Icon(Icons.visibility_off)
                              : const Icon(Icons.visibility),
                          onPressed: () {
                            _isVisible.value = !_isVisible.value;
                          },
                        ),
                        contentPadding: const EdgeInsets.all(10),
                      ),
                    ),
                    const SizedBox(
                      height: 10,
                    ),
                    if (_authMode.value == AuthMode.register)
                      TextFormField(
                        focusNode: _confirmFocusScope,
                        // controller: _passwordController,
                        textInputAction: TextInputAction.done,
                        // onFieldSubmitted: (_) {
                        //   FocusScope.of(context)
                        //       .requestFocus(_confirmFocusScope);
                        // },
                        // onEditingComplete: FocusScope.of(context)
                        //     .unfocus(),
                        key: const ValueKey('confirm'),
                        obscureText: _isVisible.value,
                        validator: (value) {
                          if (value != _passwordController.text) {
                            return 'Passwords do not match!';
                          }
                          return null;
                        },
                        decoration: kTextInputDecoration.copyWith(
                          labelText: 'Confirm Password',
                          filled: true,
                          fillColor: Theme.of(context).cardColor,
                          prefixIcon: const Icon(
                            Icons.lock,
                            size: 30,
                          ),
                          suffixIcon: IconButton(
                            icon: _isVisible.value
                                ? const Icon(Icons.visibility_off)
                                : const Icon(Icons.visibility),
                            onPressed: () {
                              _isVisible.value = !_isVisible.value;
                            },
                          ),
                          contentPadding: const EdgeInsets.all(10),
                        ),
                      ),
                    const SizedBox(
                      height: 20,
                    ),
                    MyButton(
                      text: _authMode.value == AuthMode.login
                          ? 'Login'
                          : 'Sign Up',
                      txtColor: Colors.white,
                      txtSize: 20,
                      bgColor: Colors.deepPurple,
                      onTap: () {
                        FocusScope.of(context)
                            .unfocus(); // used to dismiss the keyboard
                        _submit();
                        _authMode.value == AuthMode.login
                            ? ref
                                .read(authRepositoryProvider)
                                .login(email, password)
                            : ref.read(authRepositoryProvider).register(
                                  context,
                                  email,
                                  password,
                                  name,
                                  phone,
                                );
                      },
                    )
                  ],
                ),
              ),
            ),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Center(
                child: TextButton(
                  onPressed: () {
                    _authMode.value == AuthMode.login
                        ? _authMode.value = AuthMode.register
                        : _authMode.value = AuthMode.login;
                  },
                  child: Text(
                    '${_authMode.value == AuthMode.login ? 'No account? Sign Up' : 'Have Account? Login'} ',
                    style: const TextStyle(fontSize: 16),
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

LandingScreen to enable access to respective authentication screens



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source