流生成器中的文本字段导致小部件重新加载

问题描述 投票:0回答:1

我的 TextField 小部件遇到问题。每次用户点击它们时,整个小部件都会重新加载,并且键盘会消失。我相信我将问题追溯到主要检查用户身份验证的流构建器。这是我的 main.dart 中 MyApp 小部件的摘要版本:

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // this widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    SizeConfig.init(context);
    final auth = FirebaseAuth.instance;
    return MultiProvider(
      providers: [
        //Providers go in here...
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'livit',
        theme: ThemeData.dark().copyWith(
          scaffoldBackgroundColor: mobileBackgroundColor,
        ),
        home: StreamBuilder(
          stream: auth.authStateChanges(),
          builder: (context, snapshot) {
            //over here we have logic to go to the login screen or the main page
          },
        ),
      ),
    );
  }
}

应用程序检查用户是否已通过身份验证后,会将用户带到登录屏幕或主页。这就像一种魅力。不幸的是,用户尝试点击任何文本字段,他们无法输入,因为一旦他们聚焦,小部件就会重新加载。

所以我制作了一个干净的 flutter 项目,并编写了一个小部件来测试一切是否正常:

class TextInputTest extends StatefulWidget {
  const TextInputTest({super.key, required this.title});

  final String title;

  @override
  State<TextInputTest> createState() => _TextInputTestState();
}

class _TextInputTestState extends State<TextInputTest> {
  final TextEditingController _controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: TextField(
          controller: _controller,
        ),
      ),
    );
  }
}

它成功了,太棒了!我想指出的是,我所有使用文本字段的屏幕的格式都类似,因为它们是有状态的,并且控制器是在状态内声明的。

现在,如果我将完美工作的测试小部件放在流构建器通常所在的位置,那么该小部件就可以正常工作。但是,如果我替换登录屏幕或主页,测试小部件会出现同样的问题,整个小部件将在焦点上重新加载,并且用户将永远无法拉出屏幕。

你能帮我解决这个问题吗?我有点需要我的用户能够输入内容。

预先感谢您提供的任何帮助,如果您需要更多信息,请告诉我!

PS:我确实检查了这个帖子,但所有答案似乎都没有成果。

flutter firebase dart firebase-authentication stream-builder
1个回答
0
投票

事实证明,通过将调用

auth.authStateChanges()
放入构建方法中(在本例中位于命名的
stream
参数中),每次调用构建时都会调用并重新创建流。每当键盘被拉起时,都会调用构建,因此将所有内容设置回原来的状态,包括我的文本字段处于初始的、未聚焦的状态。

这种情况下的解决方案是使小部件有状态(如果它还没有),声明一个变量以将流保持在状态中(而不是在任何方法中),然后为其指定值

auth.authStateChanges()
。就我而言,我必须使变量延迟并使用覆盖 initState() 来设置值,因为无法在初始化程序中访问 auth。

非常感谢Randal Schwartz发现了这个问题并发布了他的视频解释来解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.