在焦点上,我的textFormFields或textFields触发了不必要的重建,尖峰资源耗尽,使模拟器和计算机变慢,甚至无法使用。我对此做了大量的研究。这似乎是一个相当大的问题&我一直未能解决它。
我尝试过的:
static final GlobalKey<FormState> _signInFormKey = GlobalKey<FormState>();
到目前为止,一切都不起作用。
我做错什么了吗?
或者这是热烈的状态管理问题的颤栗寿命--大量的X60 the刷新资源流失?
以下是表单字段:
class CustomFormField extends StatefulWidget {
const CustomFormField({
Key? key,
required TextEditingController controller,
required bool prefixCurrencySymbol,
required String? currencySymbol,
required List<String> autoFillHints,
required bool blockSystemKeyboard,
required double width,
required FocusNode focusNode,
required TextInputType keyboardType,
required TextInputAction inputAction,
required String label,
required TextCapitalization textCapitalization,
required Function(String value) validator,
required bool obscurePasswordOption,
required bool saveAutofillData,
required bool passwordCreationField,
required Future<void> Function(String?)? onChanged,
}) : _formController = controller,
_prefixCurrencySymbol = prefixCurrencySymbol,
_currencySymbol = currencySymbol,
_autoFillHints = autoFillHints,
_blockSystemKeyboard = blockSystemKeyboard,
_width = width,
_formFocusNode = focusNode,
_keyboardType = keyboardType,
_inputAction = inputAction,
_textCapitalization = textCapitalization,
_label = label,
_validator = validator,
_obscurePasswordOption = obscurePasswordOption,
_saveAutofillData = saveAutofillData,
_passwordCreationField = passwordCreationField,
_onChanged = onChanged,
super(key: key);
final TextEditingController _formController;
final bool _prefixCurrencySymbol;
final String? _currencySymbol;
final List<String> _autoFillHints;
final bool _blockSystemKeyboard;
final double _width;
final FocusNode _formFocusNode;
final TextInputType _keyboardType;
final TextInputAction _inputAction;
final String _label;
final bool _obscurePasswordOption;
final TextCapitalization _textCapitalization;
final Function(String) _validator;
final bool _saveAutofillData;
final bool _passwordCreationField;
final Future<void> Function(String?)? _onChanged;
@override
State<CustomFormField> createState() => _CustomFormFieldState();
}
class _CustomFormFieldState extends State<CustomFormField> {
bool _obscurePassword = true;
@override
void dispose() {
widget._formFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SizedBox(
width: widget._width,
child: TextFormField(
style: ThemeEndpoints.textFieldTextStyle(),
autofillHints: widget._autoFillHints,
enableInteractiveSelection: true,
enableSuggestions: false,
autocorrect: false,
textAlignVertical: const TextAlignVertical(y: 0.1),
readOnly: widget._blockSystemKeyboard,
maxLines: 1,
controller: widget._formController,
focusNode: widget._formFocusNode,
keyboardType: widget._keyboardType,
obscureText: (widget._obscurePasswordOption) ? _obscurePassword : false,
textCapitalization: widget._textCapitalization,
textInputAction: widget._inputAction,
validator: (text) => widget._validator(text!),
onChanged: (text) => (widget._passwordCreationField && text.isNotEmpty)
? widget._onChanged!(text)
: null,
onEditingComplete:
(widget._saveAutofillData) ? () => TextInput.finishAutofillContext() : null,
toolbarOptions: const ToolbarOptions(
copy: true,
paste: true,
cut: true,
selectAll: true,
),
decoration: InputDecoration(
filled: true,
fillColor: ThemeEndpoints.textFieldBackgroundColor(),
alignLabelWithHint: true,
labelText: widget._label,
labelStyle: ThemeEndpoints.textFieldLabelStyle(),
contentPadding: const EdgeInsets.fromLTRB(32, 24, 12, 16),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
width: 0,
style: BorderStyle.none,
),
),
errorStyle: ThemeEndpoints.textFieldErrorTextStyle(),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
color: BrandColors.appLightRed,
width: 2,
),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
color: BrandColors.appRed,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
borderSide: const BorderSide(
color: BrandColors.luckyLime,
width: 2,
),
),
prefixIconConstraints: (widget._prefixCurrencySymbol)
? const BoxConstraints(minWidth: 0, minHeight: 0)
: null,
prefixIcon: (widget._prefixCurrencySymbol)
? Container(
margin: const EdgeInsets.all(13),
child: Text(
widget._currencySymbol!,
style: ThemeEndpoints.textFieldCurrencySymbolTextStyle(),
),
)
: null,
suffixIcon: (widget._obscurePasswordOption)
? GestureDetector(
onTap: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
child: Container(
margin: const EdgeInsets.all(13),
child: _obscurePassword
? ThemeEndpoints.textFieldPasswordNotVisible()
: ThemeEndpoints.textFieldPasswordVisible(),
),
)
: null,
),
),
);
}
}
这是我的表格:
class SignInForm extends ConsumerWidget {
final FocusNode emailFocusNode;
final FocusNode passwordFocusNode;
SignInForm({
Key? key,
required this.emailFocusNode,
required this.passwordFocusNode,
}) : super(key: key);
final TextEditingController _email = TextEditingController();
final TextEditingController _password = TextEditingController();
static final GlobalKey<FormState> _signInFormKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context, WidgetRef ref) {
return AutofillGroup(
child: Form(
key: _signInFormKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
TextContent.of(context).authSignInText,
style: ThemeEndpoints.primaryHeader(),
),
const SizedBox(height: 16.0),
CustomFormField(
controller: _email,
onChanged: null,
prefixCurrencySymbol: false,
currencySymbol: null,
autoFillHints: const [AutofillHints.email],
blockSystemKeyboard: false,
width: 90.w,
focusNode: emailFocusNode,
keyboardType: TextInputType.emailAddress,
inputAction: TextInputAction.next,
label: TextContent.of(context).authFormEmailText,
textCapitalization: TextCapitalization.none,
validator: (email) => FormValidationUtility.emailFormValidator(
context,
email,
),
obscurePasswordOption: false,
saveAutofillData: false,
passwordCreationField: false,
),
const SizedBox(height: 16.0),
CustomFormField(
controller: _password,
onChanged: null,
prefixCurrencySymbol: false,
currencySymbol: null,
autoFillHints: const [AutofillHints.password],
blockSystemKeyboard: false,
width: 90.w,
focusNode: passwordFocusNode,
keyboardType: TextInputType.visiblePassword,
inputAction: TextInputAction.done,
label: TextContent.of(context).authFormPasswordText,
textCapitalization: TextCapitalization.none,
validator: (password) => FormValidationUtility.passwordGeneralValidator(
context,
password,
),
obscurePasswordOption: true,
saveAutofillData: false,
passwordCreationField: false,
),
const SizedBox(height: 64.0),
CustomButton(
buttonText: TextContent.of(context).authSignInText,
width: 50.w,
onPressed: () async => _onSignInPressed(
context,
ref,
[emailFocusNode, passwordFocusNode],
),
),
const SizedBox(height: 16.0),
const SignUpInkwell(),
const SizedBox(height: 16.0),
const SignInOptionsPulldown(),
],
),
),
);
}
// On pressed button execution
Future<void> _onSignInPressed(
BuildContext context,
WidgetRef ref,
List<FocusNode> focusNodes,
) async {
for (FocusNode node in focusNodes) {
node.unfocus();
}
if (_signInFormKey.currentState!.validate()) {
await ref.read(authenticationEndpoints).signIn(
context: context,
email: _email.text.trim(),
password: _password.text.trim(),
);
}
}
}
发布于 2022-10-09 07:40:02
上个星期我刚刚面对这个问题,发现在github问题上有很长时间的讨论。但是我忘了标记这个问题,所以我不能把它提交给你。
有两点我明白:
StatefullWidget
。这里的问题与此相关:https://stackoverflow.com/a/50584602/12838877在您的例子中,您有父状态小部件和一些CustomTextField
,这是一个状态小部件。
上周我的问题解决方案:
StatelessWidget
或StatefullWidget
。这将不会重建整个小部件树。StatefullWidget
的每个组件分配特定的valueKey。即使当我调用setState
并重新执行build
方法时,由于我的valueKey是相同的,小部件也不会重新构建。就像下面
CustomFormField(
key: ValueKey('emailform'),
controller: _email,
onChanged: null,
....),
CustomFormField(
key: ValueKey('pswdForm'),
controller: pswd`,
onChanged: null,
....)
https://stackoverflow.com/questions/74002668
复制相似问题