如何在构建有状态小部件之前等待功能? [复制]

Posted

技术标签:

【中文标题】如何在构建有状态小部件之前等待功能? [复制]【英文标题】:How to await on a function before Build in a stateful widget? [duplicate] 【发布时间】:2020-12-08 21:00:31 【问题描述】:

我正在等待一个 GEOLOCATOR 函数从用户那里获取位置。但是在最初的构建过程中,在从 GEOLOCATOR 实际检索到位置之前,我总是会在几秒钟内收到一个错误(纬度被调用为 null)。如何在构建页面之前实际获取 LOCATION?

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

class DistancingPage extends StatefulWidget 
  DistancingPage(this.uid);
  @override
  _DistancingPageState createState() => _DistancingPageState();


class _DistancingPageState extends State<DistancingPage> 
Position position;

@override
  void initState() 
    super.initState();
    getPos();
  

  Future<void> getPos() async 
    Position p = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);

    setState(() 
      position = p;
    );
  
@override
  Widget build(BuildContext context) 
return Scaffold(
        appBar: AppBar(
          title: Text('Distancing Alerts'),
          backgroundColor: Colors.red[800],
),
body: Padding(
            padding: const EdgeInsets.all(36.0),
            child: Column(
              children: [
                Text(
                  'YOUR CURRENT POSITION',
                  style: TextStyle(
                    color: Colors.red[800],
                  ),
                ), //THE ERROR OCCURS HERE
                Text(position.latitude.toString() +
                    '° N , ' +
                    position.longitude.toString() +
                    '° E'),
],
            )));
  



【问题讨论】:

你不能这样做,在构建 UI 时你不能等待未来,但是一旦数据可用,你可以更新 UI,为此使用 FutureBuilder 【参考方案1】:

您应该使用FutureBuilder 小部件,其中future 是您的异步​​函数,而builder 是您想要返回的任何东西(在您的情况下是脚手架)。使用snapshot.hasData 检查future 是否返回了任何内容,如果没有返回任何内容,则返回进度指示器(或您想要的任何内容)。

    FutureBuilder(
      future: getPos(),
      builder: (context, snapshot) 
    snapshot.hasData ? 
      Scaffold(
                appBar: AppBar(
                  title: Text('Distancing Alerts'),
                  backgroundColor: Colors.red[800],
        ),
        body: Padding(
                    padding: const EdgeInsets.all(36.0),
                    child: Column(
                      children: [
                        Text(
                          'YOUR CURRENT POSITION',
                          style: TextStyle(
                            color: Colors.red[800],
                          ),
                        ), //THE ERROR OCCURS HERE
                        Text(position.latitude.toString() +
                            '° N , ' +
                            position.longitude.toString() +
                            '° E'),
        ],
                    ))) : CircularProgressIndicator();;

【讨论】:

【参考方案2】:

您可以添加一个带有来自 flutter_spinkit 的动画的临时页面。在该页面上,您正在等待 GEOLOCATOR 函数,当它返回一个值时,您将导航到主屏幕

【讨论】:

或者如果应用在前台,你可以在后台获取位置,有文章如何做到这一点medium.com/@pierre.sabot/…

以上是关于如何在构建有状态小部件之前等待功能? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

setState() 如何重建子部件?

私人JavaScript小部件

Magento 2 创建 Widget

派生 QMainWindow 并更改其布局

如何在 Qt 表单类中调整 OpenGL 小部件的大小

如何从另一个小部件状态处理一个小部件状态?