【问题标题】:How to get the data after we Navigate to another page in flutter我们在flutter中导航到另一个页面后如何获取数据
【发布时间】:2020-08-06 18:35:49
【问题描述】:

我想在我们发布新数据后获取数据。现在我需要重新打开应用程序以获取插入的数据。像图片一样,我在下面显示。在主页,详细信息来自响应 JSON。 主页有一个按钮转到添加数据页。在我单击按钮转到 添加数据页面 之后,在添加了 电子邮件、用户名 数据后,我使用 Navigator.of(context).pop( );.问题是数据没有更新,我需要重新打开应用才能看到新插入的数据。

这是我的主页代码:

Future getDetails() async {
    http.Response response = await http.get(url);
    var decodedData = json.decode(response.body);

    setState(() {
      email= decodedData['email'];
      username= decodedData['username'];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
       appBar: AppBar(title: Text('Home page'),
      ),
       body: SingleChildScrollView(
         child: Column(
         children: <Widget> [
          new Row(
            children: [
             Text('  Name: '+ username, style: TextStyle(fontSize: 16), textAlign: TextAlign.left,),
            Text('  Email : '+ email, style: TextStyle(fontSize: 16), textAlign: TextAlign.left,),
          ]
          ),
          new Row(
            children: [
              SizedBox(
                width: 350, 
                child: OutlineButton(
                  child: Text('ADD DATA'),
                  onPressed: () {Navigator.of(context).push(MaterialPageRoute(builder: (context) => AddPage()));},
                )
              )
            ]
          ),
          ]
          ),
       )
    );
  }

这是我的添加数据页面代码:

Future<void> addDetails() async {
    setState(() {
      loading = true;
    });

    http.Response response = await http.post(url, 
      body: {
        'username': usernameController.text,
        'email': emailController.text,
      }
    );
    setState(() {
      loading = true;
      Navigator.pop(context);
    });
  }

有谁知道如何解决这个问题?谢谢。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    首先,您必须将Navigator#pop 方法的结果更改为awaitNavigator#pop 有一个带有另一个参数的签名,它将在主页上被接受。您可以在主页中尝试类似的操作。

    new Row(
       children: [
         SizedBox(
             width: 350, 
             child: OutlineButton(
                child: Text('ADD DATA'),
                onPressed: () async {
                  final List<String> pageResult = await Navigator.of(context).push(MaterialPageRoute(builder: (context) => AddPage()));
    
                  setState(() {
                    email = pageResult[0];
                    userName = pageResult[1];
                  });
              },
            )
          )
       ]
    );
    

    然后在您的其他页面的弹出部分执行此操作:

    setState(() {
      loading = false; //This is a bug in your code
      Navigator.pop(context, [emailController.text, userNameController.text]);
    });
    

    【讨论】:

    • 感谢您的回复。我也只是编辑我的问题添加用户名。如果添加用户名需要这样写 Navigator.pop(context, usernameController.text.emailController.text);?
    • 更新了答案。除了上下文之外,您还可以传递一组结果。并设置值。如果对您有帮助,请接受并投票。谢谢!
    • 您可以将代码粘贴到您的导航弹出呼叫吗?您是否传递了一个数组作为第二个参数?
    • 在我再次flutter tun之后已经可以了。感谢您的帮助
    • 我认为值得一提的是,在 MaterialApp 中设置路由时需要初始化 Map() 的参数
    【解决方案2】:

    在您的主页中调用initState() 函数:

    WidgetsBinding.instance.addPostFrameCallback((_){ getDetails(); });

    编辑:将推送替换为以下内容

    Navigator.of(context).push(MaterialPageRoute(builder: (context) => AddPage())).then((_){getDetails();});
    

    【讨论】:

    • 感谢您的回复,我已经尝试过但没有更改。它仍然需要重新打开应用才能获取最新的详细信息
    • 我收到有关“数据!= null”的错误:必须向文本小部件提供非空字符串。
    • 初始化字符串或处理文本小部件中的空值,如下所示:用户名?? ''
    【解决方案3】:

    您可以将弹出路由的结果返回到HomePage

    在添加数据页面内:

    setState(() {
          loading = true;
          Navigator.pop(context,email);
        });
    

    HomePage内:

    OutlineButton(
          child: Text('ADD DATA'),
          onPressed: () async {
            final String returnedEmail = await Navigator.of(context)
                .push(MaterialPageRoute(builder: (context) => AddPage()));
            setState(()=>email = returnedEmail);
          },
        );
    

    【讨论】:

    • 感谢您的回复。我也只是编辑我的问题添加用户名。我试过你的答案它不能工作
    • @dipgirl 它不起作用不是因为它没有解决您的问题中的问题,而是因为您的代码中有错字:您总是在加载真实
    【解决方案4】:

    我认为有办法解决你的问题:

    1。使用GlobalKey 识别您的HomePage

    您必须在单独的文件(例如keys.dart)中创建一个GlobalKey,它将标识您的HomePage 小部件。这将使HomePageState 类公开。

    // In the keys.dart file
    final GlobalKey<HomePageState> homePageKey = GlobalKey();
    

    创建密钥后,在AddDataPage 上使用它,如下所示:

    // Import your keys.dart file, and when Calling your HomePage in the build() method, specify the key
    HomePage(
      key: homePageKey,
      ...
    )
    

    2。使用密钥刷新您的HomePage - 需要时-

    现在在您的 addDetails() 方法中,您可以使用您的 GlobalKey 刷新 HomePage

    Future<void> addDetails() async {
        setState(() {
          loading = true;
        });
    
        http.Response response = await http.post(url, 
          body: {
            'email': emailController.text,
          }
        );
    
        // Make this setState callback async, and refresh your HomePage
        setState(() async {
          loading = false;
          await homePageKey.currentState.getDetails();
          Navigator.pop(context);
        });
    
        // Or you can also invert things (here the home page will be shown before refresh, useful if the getDetails() method show a kind of progress bar)
        // setState(() async {
        //   loading = false;
        //   await Navigator.pop(context);
        //   homePageKey.currentState.getDetails();
        // });
    
    }
    

    希望这会有所帮助!

    【讨论】:

    • 在我的 homepage.dart 中,我已经有了 GlobalKey paginatorGlobalKey = GlobalKey();
    • 这个不能用于HomePage 小部件,因为这个键引用了PaginatorState(我认为它不是HomePage 小部件的状态类)。您必须创建一个引用 HomePageStateGlobalKey 才能将其与 HomePage 小部件一起使用
    【解决方案5】:
    1. 推送导航
    新的 Future.delayed( const 持续时间(秒:5), () => 导航器.push( 语境, MaterialPageRoute(builder: (context) => SignScreen()), ));
    1. 路线导航
    点按: () => Navigator.pushReplacement( 语境, new MaterialPageRoute(builder: (context) => new SignInScreen()),

    【讨论】:

      猜你喜欢
      • 2020-05-24
      • 1970-01-01
      • 2021-09-11
      • 2020-09-03
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2020-09-26
      • 2022-01-09
      相关资源
      最近更新 更多