Futurebuilder 内的导航

Har*_* .S 1 routes flutter flutter-futurebuilder flutter-go-router

我正在尝试在 futurebuilder 中登录后进行导航。api 请求成功完成,但测试时导航出错。帮助我如何正确使用 futurebuilder。

child: ElevatedButton(
                onPressed: () {
                  // Validate returns true if the form is valid, or false otherwise.
                  if (_mobileKey.currentState!.validate()) {
                    FutureBuilder<Loginuser>(
                      future: loginuser(mobileController.text.toString(),
                          passwordController.text.toString()),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          context.go('/Home');
                          return Text(snapshot.data!.message);
                        } else if (snapshot.hasError) {
                          return Text('${snapshot.error}');
                        }

                        // By default, show a loading spinner.
                        return const CircularProgressIndicator();
                      },
                    );
                  }

                  context.go('/Home');
                },
                child: const Text('Submit')),
Run Code Online (Sandbox Code Playgroud)

我试过这个它不起作用。我使用“ go_router: ^5.2.4 ”进行导航

Men*_*elG 5

TLDR:添加:

 WidgetsBinding.instance.addPostFrameCallback((_) =>
                context.go('/Home'));

Run Code Online (Sandbox Code Playgroud)

FutureBuilder


我成功地用这个例子重现了这个问题。让我们来看看。

如果您运行此代码:

import 'package:flutter/material.dart';

void main() => runApp(MainApp());

class MainApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(body: Test()),
    );
  }
}

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: printHello(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => HomePage()));

            return Text(snapshot.data.toString());
          } else if (snapshot.hasError) {
            return Text("error");
          } else {
            return Center(child: CircularProgressIndicator());
          }
        });
  }
}

Future<String> printHello() async {
  return Future.value("Hello");
}

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: const Text("home page"));
  }
}
Run Code Online (Sandbox Code Playgroud)

你会看到一个错误:

setState() or markNeedsBuild() called during build.
Run Code Online (Sandbox Code Playgroud)

因此,要解决该问题,您需要使用WidgetsBinding.instance.addPostFrameCallback

setState() or markNeedsBuild() called during build.
Run Code Online (Sandbox Code Playgroud)

但对于您的示例go_router,请添加以下行:

WidgetsBinding.instance.addPostFrameCallback((_) =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return HomePage();
                })));

Run Code Online (Sandbox Code Playgroud)

完整的工作示例:

 WidgetsBinding.instance.addPostFrameCallback((_) =>
                context.go('/Home'));
Run Code Online (Sandbox Code Playgroud)

也可以看看

构建期间调用 setState() 或 markNeedsBuild