dart 如何将数据从API传递到Flutter UI

pxy2qtax  于 2024-01-03  发布在  Flutter
关注(0)|答案(2)|浏览(118)

我试图从开放的天气API向flutter用户界面传递数据。我认为这与我在哪里初始化城市名称变量有关,因为它在每次刷新应用程序时都会重新构建,并且只加载原始字符串而不是我放在文本字段中的城市。我如何修复此代码,以便我可以使用新的城市名称从API中提取信息。

  1. import 'package:flutter/material.dart';
  2. import 'package:weather_solo/logic/get_weather.dart';
  3. //import 'logic/additional_information_info.dart';
  4. import 'logic/weather_forecast_time.dart';
  5. class WeatherHomePage extends StatefulWidget {
  6. const WeatherHomePage({super.key});
  7. @override
  8. State<WeatherHomePage> createState() => _WeatherHomePageState();
  9. }
  10. class _WeatherHomePageState extends State<WeatherHomePage> {
  11. TextEditingController cityNameController = TextEditingController();
  12. GetWeather getWeather = GetWeather();
  13. String cityName = 'Hamilton';
  14. late Future<Map<String, dynamic>> weather = getWeather.getCurrentWeather(cityName);
  15. // late int iconID = weather['list'][0];
  16. //list[0].weather[0].id
  17. @override
  18. void initState() {
  19. super.initState();
  20. weather = getWeather.getCurrentWeather(cityName);
  21. }
  22. @override
  23. Widget build(BuildContext context) {
  24. return SafeArea(
  25. child: Scaffold(
  26. appBar: AppBar(
  27. centerTitle: true,
  28. title: const Text('My Weather App',
  29. style: TextStyle(
  30. fontSize: 20,
  31. ),),
  32. ),
  33. body: Padding(
  34. padding: const EdgeInsets.all(8.0),
  35. child: Column(
  36. children: [
  37. Card(
  38. elevation: 10,
  39. child: Padding(
  40. padding: const EdgeInsets.all(8.0),
  41. child: Column(
  42. children: [
  43. TextField(
  44. controller: cityNameController,
  45. decoration: const InputDecoration(
  46. hintText: 'Please Enter City Name Here',
  47. border: OutlineInputBorder()
  48. ),
  49. ),
  50. ElevatedButton(onPressed: () {
  51. setState(() {
  52. cityName = cityNameController.text;
  53. cityNameController.clear();
  54. getWeather.getCurrentWeather(cityName);
  55. });
  56. },
  57. style: const ButtonStyle(
  58. elevation: MaterialStatePropertyAll(10),
  59. backgroundColor:
  60. MaterialStatePropertyAll(Colors.red),
  61. foregroundColor: MaterialStatePropertyAll(Colors.black),
  62. ),
  63. child: const Text(
  64. 'Choose City'
  65. ),
  66. ),
  67. ],
  68. ),
  69. ),
  70. ),
  71. // Flex for weather data, needs to be wrapped in a FutureBuilder as this is the section that will update
  72. FutureBuilder(
  73. future: weather,
  74. builder: (context, snapshot) {
  75. if(snapshot.connectionState == ConnectionState.waiting) {
  76. return const Center(
  77. child: CircularProgressIndicator.adaptive(),
  78. );
  79. }
  80. if (snapshot.hasError) {
  81. return Center(
  82. child: Text(snapshot.error.toString()),
  83. );
  84. }
  85. final data = snapshot.data!;
  86. final currentWeatherData = data['list'][0];
  87. final currentIcon = currentWeatherData['weather'][0]['id'];
  88. return Expanded(
  89. child: Column(
  90. mainAxisAlignment: MainAxisAlignment.spaceAround,
  91. children: [
  92. Card(
  93. elevation: 10, //Main weather data card
  94. child: Column(
  95. mainAxisAlignment: MainAxisAlignment.spaceAround,
  96. children: [
  97. const SizedBox(width: double.infinity,),
  98. Text(cityName,
  99. style: const TextStyle(
  100. fontSize: 15,
  101. ),),
  102. const SizedBox(height: 10,),
  103. Text('Weather icon code $currentIcon Rain',
  104. style: const TextStyle(
  105. fontSize: 10
  106. ),),
  107. const SizedBox(
  108. height: 5,
  109. ),
  110. const Icon(Icons.cloud,
  111. size: 20,),
  112. const SizedBox(height: 5,),
  113. const Text('27 °C',
  114. style: TextStyle(
  115. fontSize: 20
  116. ),) //Hold down left alt and numpad 0176 for degree symbol
  117. ],
  118. ),
  119. ),
  120. // Wetaher data time forecast
  121. SizedBox(
  122. height: 100,
  123. child: ListView.builder(itemCount: 5,scrollDirection: Axis.horizontal,itemBuilder: (context ,index) {
  124. return const WeatherForecastTime(time: '09.00', icon: Icons.sunny, desctription: 'Sunny',);
  125. },
  126. ),
  127. ),
  128. //Additional information
  129. // const Row(
  130. // mainAxisAlignment: MainAxisAlignment.spaceAround,
  131. // children: [
  132. // AdditionalInformationInfo(title: 'Humidity', icon: Icons.water_drop, stats: '4757',),
  133. // AdditionalInformationInfo(title: 'Wind Speed', icon: Icons.air, stats: 'Fast',),
  134. // AdditionalInformationInfo(title: 'Pressure', icon: Icons.umbrella, stats: '775',)
  135. // ],
  136. // ),
  137. ],
  138. ),
  139. );
  140. }
  141. )
  142. ],
  143. ),
  144. ),
  145. ),
  146. );
  147. }
  148. }

个字符

vyu0f0g1

vyu0f0g11#

这个修好了

  1. ElevatedButton(onPressed: () {
  2. setState(() {
  3. cityName = cityNameController.text;
  4. cityNameController.clear();
  5. weather = getWeather.getCurrentWeather(cityName);
  6. });
  7. },

字符串

lrpiutwd

lrpiutwd2#

您遇到的问题是由于初始化cityName变量的位置。正如您提到的,它是在类级别初始化的,这导致它在小部件的整个生命周期中保持其原始值,即使在更新文本字段之后也是如此。要解决此问题并确保使用更新的城市名称来获取天气数据,您应该将API调用移动到ElevatedButton的onPressed方法中的getCurrentWeather

  1. ElevatedButton(
  2. onPressed: () {
  3. setState(() {
  4. final cityName = cityNameController.text;
  5. cityNameController.clear();
  6. weather = getWeather.getCurrentWeather(cityName);
  7. });
  8. }

字符串

相关问题