You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter 点击按钮首次不加载天气数据 第二次点击才正常加载问题求助

问题原因

你当前代码的执行逻辑是点击按钮后同时触发异步定位+天气请求、同步弹出对话框两个任务,异步请求还未执行完成、_data仍为空数组时,对话框已完成渲染,因此首次点击无数据展示。第二次点击时前一次请求已经把数据存入_data,因此可以正常展示内容。

解决方法

调整执行顺序,等异步的定位和天气请求全部执行完成后,再弹出对话框,修改步骤如下:

  • 将queryWeather方法返回值修改为Future<void>
  • 将getCurrentLocation方法返回值修改为Future<void>,调用queryWeather时增加await关键字
  • 按钮onPressed改为异步函数,先await getCurrentLocation执行完成,再调用showDialog弹出对话框
修改后完整代码
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:weather/weather.dart';

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

class MyAppp extends StatefulWidget {
  const MyAppp({ Key? key }) : super(key: key);

  @override
  _MyApppState createState() => _MyApppState();
}

class _MyApppState extends State<MyAppp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home:ButtonPage()
    );
  }
}

class ButtonPage extends StatefulWidget {
  const ButtonPage({ Key? key }) : super(key: key);

  @override
  _ButtonPageState createState() => _ButtonPageState();
}

class _ButtonPageState extends State<ButtonPage> {
  String key = '856822fd8e22db5e1ba48c0e7d69844a';
  late WeatherFactory ws;
  List<Weather> _data = [];
  double? lat, lon;
  // 加载状态避免重复点击
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    ws = WeatherFactory(key);
  }

  Future<void> getCurrentLocation() async {
    var position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.high);
    var lat = position.latitude;
    var long = position.longitude;
    print(lat);
    print(long);
    await queryWeather(lat,long);
  }

  Future<void> queryWeather(var lat,var long) async {
    print("Data: "+_data.toString());
    FocusScope.of(context).requestFocus(FocusNode());
    Weather weather = await ws.currentWeatherByLocation(lat, long);
    setState(() {
      _data = [weather];
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: RaisedButton(
        onPressed: _isLoading ? null : () async {
          setState(() {
            _isLoading = true;
          });
          try {
            await getCurrentLocation();
            if(!mounted) return;
            showDialog<void>(
              context: context,
              builder: (BuildContext context) {
                return Dialog(
                  child: Center(
                    child: ListView.builder(
                      shrinkWrap: true,
                      itemCount: _data.length,
                      itemBuilder: (context, index) {
                        return ListTile(
                          title: Text("${_data[index].areaName}"),
                        );
                      },
                    ),
                  ),
                );
              },
            );
          } catch(e) {
            // 可自行添加定位失败、网络请求失败的提示逻辑
            print(e);
          } finally {
            if(mounted) {
              setState(() {
                _isLoading = false;
              });
            }
          }
        },
        child: _isLoading ? CircularProgressIndicator(color: Colors.white,) : Text("Button"),
      ),),
    );
  }
}
补充说明

如果想要更流畅的用户体验,也可以选择先弹出带加载动画的对话框,等天气数据请求完成后再更新对话框内容,避免用户在网络较慢时等待无反馈。

内容的提问来源于stack exchange,提问作者Deepak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:48:05