dart Flutter AutoFillGroup/Autofill提示不工作

h5qlskok  于 9个月前  发布在  Flutter
关注(0)|答案(2)|浏览(166)

我的代码显示并提交登录表单:

class LoginWidget extends StatelessWidget {
  const LoginWidget({
    super.key,
  });

 @override
  Widget build(BuildContext context) {
    final citiesLoaded = context.select((LoginBloc bloc) => bloc.state.citiesLoaded);
    final loginBloc = context.read<LoginBloc>();

    final selectedCity = (citiesLoaded && loginBloc.state.cities.length == 1)
        ? loginBloc.state.cities[0]
        : context.select((LoginBloc bloc) => bloc.state.selectedCity);

    final formValidator = context.select((LoginBloc bloc) => bloc.state.formValidator);

    final theme = Theme.of(context).extension<LoginPageThemeData>();

    return AutofillGroup(
      child: Column(
        children: [
          citiesLoaded
              ? Visibility(
                  visible: loginBloc.state.cities.length > 1,
                  child: CitySelectWidget(selectedCity: selectedCity),
                )
              : const BusyWidget(status: 'Loading cities'),
          Text('Username:'),
          TextFormField(
              autofillHints: const [AutofillHints.username, AutofillHints.email, AutofillHints.name],
              enabled: selectedCity != null,
              initialValue: loginBloc.state.username,
              keyboardType: TextInputType.emailAddress,
              decoration: theme?.inputDecoration
                  ?.copyWith(errorText: formValidator.usernameField.isValid ? null : formValidator.usernameField.validationMessage),
              onChanged: (value) => loginBloc.add(SetUsernameEvent(username: value))),
          Text('Password:'),
          TextFormField(
              autofillHints: const [AutofillHints.username, AutofillHints.email, AutofillHints.name],
              enabled: selectedCity != null,
              initialValue: loginBloc.state.password,
              obscureText: true,
              decoration: theme?.inputDecoration
                  ?.copyWith(errorText: formValidator.passwordField.isValid ? null : formValidator.passwordField.validationMessage),
              onChanged: (value) => loginBloc.add(SetPasswordEvent(password: value))),
          ElevatedButton(
            onPressed: selectedCity == null
                ? null
                : () {
                    context.read<app_bloc.AppBloc>().add(app_bloc.SetSelectedCityEvent(selectedCity));
                    context.read<LoginBloc>().add(const AuthEvent());
                  },
            child: Text('Sign in'),
          ),
        ],
      ),
    );
  }
}

字符串
在父部件(登录页面)显示主应用程序的页面时,自动化进程完成:

@override
  Widget build(BuildContext context) {
    return BlocListener<LoginBloc, LoginState>(
      listenWhen: (previous, current) => previous.isLogged != current.isLogged || (current.loginFailed && !current.isBusy),
      listener: (context, state) {
        if (state.isLogged) {
          Navigator.pushNamedAndRemoveUntil(context, '/home', (route) => false);
        }
        if (state.loginFailed) {
          Fluttertoast.showToast(msg: state.statusMessage);
        }
      },
      child: Scaffold( ......


所以,在提交isLogged标志将设置在认证成功后,应用程序导航到主主页+销毁登录页面。但自动填充仍然不工作。没有提示保存密码。
你知道我还需要做什么吗?

f8rj6qna

f8rj6qna1#

自动填充功能似乎存在一些问题,有时是由于设备类型,操作系统和系统设置。
自动填充服务提供程序严重依赖自动填充提示。请确保当前使用的自动填充服务支持自动填充提示中的条目(通常可以在移动终端的系统设置中找到服务名称)。
在开发过程中,我们不会自动填充,以便为许多用户提供最适合的解决方案。
但一般来说,为了获得最好的经验:
1.必须将keyboardType定义为准确的预期文本输入。
1.最好只指定一个AutofillHint类型 (所有类型都可以在here中找到),该类型最容易与您的keyboardType或TextInputType对齐,但如果您必须列出多组AutofillHint类型,则应该从与指定的keyboardType最密切相关的类型开始;特别是为了满足iOS设置为seen here的要求
某些自动填充提示仅适用于特定的keyboardType。例如,AutofillHints.name需要TextInputType.name,而AutofillHints.email仅适用于TextInputType. emailAddresss。请确保输入字段具有兼容的keyboardType。根据经验,TextInputType.name适用于iOS上预定义的许多自动填充提示。
所以你可以有

/

Text('Username:'),
TextFormField(
    autofillHints: const [AutofillHints.email, AutofillHints.name],
    enabled: selectedCity != null,
    initialValue: loginBloc.state.username,
    keyboardType: TextInputType.emailAddress,
    decoration: theme?.inputDecoration
        ?.copyWith(errorText: formValidator.usernameField.isValid ? null : formValidator.usernameField.validationMessage),
    onChanged: (value) => loginBloc.add(SetUsernameEvent(username: value))),
Text('Password:'),
TextFormField(
    keyboardType: TextInputType.visiblePassword,
    autofillHints: const [AutofillHints.password],
    enabled: selectedCity != null,
    initialValue: loginBloc.state.password,
    obscureText: true,
    decoration: theme?.inputDecoration
                  ?.copyWith(errorText: formValidator.passwordField.isValid ? null : formValidator.passwordField.validationMessage),
    onChanged: (value) => loginBloc.add(SetPasswordEvent(password: value))),
      
/

字符串

wf82jlnq

wf82jlnq2#

我测试了官方flutter bloc示例-登录流。除了他们使用formz库来简化表单验证,它几乎和我的一样。所以我在那里添加了AutofillGroup,它工作了。我终于找到了它在我的情况下不工作的原因。这是因为我使用了:

final formValidator = context.select((LoginBloc bloc) => bloc.state.formValidator);

字符串
formValidator在提交时改变(新状态是发出新的表单验证器值),所以它导致整个表单(包括AutofillGroup)重建。在这种情况下,自动填充似乎会丢失其上下文,并且不再有任何数据要保存。
解决方案是删除顶级选择并使用此选项,以确保仅在需要时刷新表单项:

BlocBuilder<LoginBloc, LoginState>(
            buildWhen: (previous, current) => previous.password != current.password || previous.formValidator != current.formValidator,
            builder: (context, state) {
              return TextFormField(
                  autofillHints: const [AutofillHints.password],
                  enabled: selectedCity != null,
                  initialValue: loginBloc.state.password,
                  obscureText: true,
                  decoration: theme.inputDecoration
                      ?.copyWith(errorText: state.formValidator.passwordField.isValid ? null : state.formValidator.passwordField.validationMessage, label: Text('Hasło')),
                  onChanged: (value) => loginBloc.add(SetPasswordEvent(password: value)));
            }


除此之外,Flutter的自动填充方法仍然不是很好。如果自动填充服务是Google,它工作得很好,但它几乎从来没有像第三方自动填充服务那样工作。在iOS上,一般来说它不工作。密码可以保存到密钥库,但自动填充对话框不会出现,我需要手动查找凭据。

相关问题