0

我在 a 中有以下代码,statefullWidget我想将其更改statefullWidget为 astatelessWidgetGetXCintroller改用。

  AnimationController? _controller;
  Animation<Offset>? _slideAnimation;
  Animation<double>? _opacityAnimation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(
        milliseconds: 300,
      ),
    );
    _slideAnimation = Tween<Offset>(
      begin: const Offset(0, -1.5),
      end: const Offset(0, 0),
    ).animate(
      CurvedAnimation(
        parent: _controller as Animation<double>,
        curve: Curves.fastOutSlowIn,
      ),
    );
    _opacityAnimation = Tween(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(
        parent: _controller as Animation<double>,
        curve: Curves.easeIn,
      ),
    );
    // _heightAnimation.addListener(() => setState(() {}));
  }

我试图把它放在onInit()方法中而不是initState()放在一个类extends GetxController with GetSingleTickerProviderStateMixin中。它似乎没有错误,但是当我在移动平台上启动应用程序时,当我尝试选择登录/注册表单上的文本字段时,它会关闭键盘。实际上,这是一个通过将表单和按钮文本从登录模式切换到注册模式来为登录/注册表单设置动画的代码。这是表单的代码:

Card(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10.0),
      ),
      elevation: 8.0,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeIn,
        height: _authMode!.value == AuthMode.Signup ? 320 : 260,
        //height: _heightAnimation.value.height,
        constraints: BoxConstraints(
            minHeight: _authMode.value == AuthMode.Signup ? 320 : 260),
        width: deviceSize.width * 0.75,
        padding: const EdgeInsets.all(16.0),
        child: Form(
              key: _formKey,
              child: SingleChildScrollView(
                child: Column(
                  children: <Widget>[
                    TextFormField(
                      decoration: const InputDecoration(labelText: 'E-Mail'),
                      keyboardType: TextInputType.emailAddress,
                      validator: (value) {
                        if (value!.isEmpty || !value.contains('@')) {
                          return 'Invalid email!';
                        }
                      },
                      onSaved: (value) {
                        _authData['email'] = value as String;
                      },
                    ),
                    TextFormField(
                      decoration: const InputDecoration(labelText: 'Password'),
                      obscureText: true,
                      controller: _passwordController,
                      validator: (value) {
                        if (value!.isEmpty || value.length < 5) {
                          return 'Password is too short!';
                        }
                      },
                      onSaved: (value) {
                        _authData['password'] = value as String;
                      },
                    ),
                    AnimatedContainer(
                      constraints: BoxConstraints(
                        minHeight: _authMode.value == AuthMode.Signup ? 60 : 0,
                        maxHeight: _authMode.value == AuthMode.Signup ? 120 : 0,
                      ),
                      duration: const Duration(milliseconds: 300),
                      curve: Curves.easeIn,
                      child: FadeTransition(
                        opacity: _opacityAnimation as Animation<double>,
                        child: SlideTransition(
                          position: _slideAnimation as Animation<Offset>,
                          child: TextFormField(
                            enabled: _authMode.value == AuthMode.Signup,
                            decoration: const InputDecoration(
                                labelText: 'Confirm Password'),
                            obscureText: true,
                            validator: _authMode.value == AuthMode.Signup
                                ? (value) {
                                    if (value != _passwordController.text) {
                                      return 'Passwords do not match!';
                                    }
                                  }
                                : null,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(
                      height: 20,
                    ),
                    if (_isLoading!.value)
                      const CircularProgressIndicator()
                    else
                      Obx(() => ElevatedButton(
                            child: Text(_authMode.value == AuthMode.Login
                                ? 'LOGIN'
                                : 'SIGN UP'),
                            onPressed: _submit,
                            style: ElevatedButton.styleFrom(
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(30),
                              ),
                              primary: Theme.of(context).primaryColor,
                              padding: const EdgeInsets.symmetric(
                                  horizontal: 30.0, vertical: 8.0),
                              onPrimary: Theme.of(context)
                                  .primaryTextTheme
                                  .button!
                                  .color,
                            ),
                          )),
                    Obx(() => TextButton(
                          child: Text(
                              '${_authMode.value == AuthMode.Login ? 'SIGNUP' : 'LOGIN'} '),
                          onPressed: _switchAuthMode,
                          style: TextButton.styleFrom(
                            padding: const EdgeInsets.symmetric(
                                horizontal: 30.0, vertical: 4),
                            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                            textStyle: TextStyle(
                                color: Theme.of(context).primaryColor),
                          ),
                        )),
                  ],
                ),
              ),
            )),
      // ),
    );

文本按钮有效(通过用 包装Obx)并且可以更改表单,但文本字段不可点击,并且键盘立即关闭并且表单再次重新启动。

4

1 回答 1

1

当您使用GetX包时,您可以选择创建一个扩展GetxController的控制器。

这是 GetXController 的示例。

class AuthController extends GetxController{
  final key = GlobalKey<FormState>();
  late TextEditingController passwordController;
  @override
  void onInit() {
    super.onInit();
    passwordController = TextEditingController();
  }
  
  @override
  void onReady() {
    super.onReady();
  }
  
  @override
  void onClose() {
    super.onClose();
    passwordController.dispose();
  }
}

GetX 中initState()的替代方法是 onInit()

请务必检查此 repo github.com/jabeed-ahmed/test。

如果它解决了您的问题,请将其标记为已回答

于 2022-02-01T05:46:18.347 回答