![](/img/trans.png)
[英]Resetting form using formKey.currentState.reset() not working
[英]Is it possible to use "formKey.currentState" inside a stateless widget with GetX?
我正在嘗試將使用提供程序 package 和有狀態小部件的代碼轉換為使用 GetX package 和無狀態小部件。 我確實遇到的一個問題是我有一個使用 animation 更改的表單(從登錄到注冊,反之亦然),但是當我檢查下一行的結果時if (._formKey.currentState!.validate())
似乎不起作用。
這是相關代碼:
auth_controller.dart:
enum AuthMode { Signup, Login }
class AuthController extends GetxController with GetSingleTickerProviderStateMixin {
static AuthController instance = Get.find();
Rx<dynamic>? authMode = AuthMode.Login.obs;
RxBool? isLoading = false.obs;
String? _token;
DateTime? _expiryDate;
String? _userId;
Timer? _authTimer;
final _isAuth = false.obs;
AnimationController? controller;
Animation<Offset>? slideAnimation;
Animation<double>? opacityAnimation;
@override
void onInit() {
super.onInit();
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(() {}));
}
.
.
.
auth_screen.dart:
return 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: Obx(() => 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
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,
),
),
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),
),
),
],
),
),
)),
),
);
我不知道問題出在哪里以及如何以正確的方式轉換代碼? 我也不知道是否有可能?
是的,您可以將 FormState 與 GetX 控制器和無狀態小部件一起使用,但是您需要在 controller 中實例化 GlobalKey,然后確保 controller 在 UI 上“放置”以供使用。
class YourController extends GetXController {
final formKey = GlobalKey<FormState>();
}
然后將 controller 作為依賴項注入到無狀態小部件中
class YourWidget extends StatelessWidget {
final getxController = Get.put(YourController());
}
然后將其添加到您的表單小部件
child: Form(
key: getxController.formKey,
將所需的驗證函數添加到 controller 和 TextInput 小部件后,您可以從 Getx 擴展中調用 formKey.Validate() controller class
void submitForm() {
final isValid = formKey.currentState.validate();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.