Flutter 颤振:构建方法在initState完成之前运行
我正在尝试用Flutter制作一个天气应用程序。但是由于某种原因,build()方法在initState()方法完成之前运行。问题是,所有状态变量都是使用initState()中的setState()方法初始化的,其变量将在build()方法中使用。我想问题在于,flift试图在setState()方法之前访问这些状态变量,这不断地向我抛出错误:必须向文本小部件提供非空字符串。我知道这些代码太长,读不懂。但如果你能帮我,我会很感激的Flutter 颤振:构建方法在initState完成之前运行,flutter,Flutter,我正在尝试用Flutter制作一个天气应用程序。但是由于某种原因,build()方法在initState()方法完成之前运行。问题是,所有状态变量都是使用initState()中的setState()方法初始化的,其变量将在build()方法中使用。我想问题在于,flift试图在setState()方法之前访问这些状态变量,这不断地向我抛出错误:必须向文本小部件提供非空字符串。我知道这些代码太长,读不懂。但如果你能帮我,我会很感激的 import 'package:flutter/materia
import 'package:flutter/material.dart';
import "package:climat/screens/LoadingScreen.dart";
import "package:climat/screens/MainScreen.dart";
import "package:climat/screens/SearchScreen.dart";
void main() {
runApp(
MaterialApp(
theme: ThemeData(
fontFamily: "Open Sans",
),
title: "Climat",
initialRoute: "/",
onGenerateRoute: (RouteSettings routeSettings) {
dynamic routes = <String, WidgetBuilder>{
"/": (context) => LoadingScreen(),
"/index": (context) => MainScreen(),
"/search": (context) => SearchScreen(),
};
WidgetBuilder builder = routes[routeSettings.name];
return MaterialPageRoute(builder: (context) => builder(context));
},
),
);
}
导入“包装:颤振/材料.省道”;
导入“包:气候/屏幕/加载屏幕.dart”;
导入“包:climat/screens/MainScreen.dart”;
导入“包:climat/screens/SearchScreen.dart”;
void main(){
runApp(
材料聚丙烯(
主题:主题数据(
fontFamily:“开放式SAN”,
),
标题:“气候”,
初始路径:“/”,
OnGeneratorOute:(路由设置路由设置){
动态路由={
“/”:(上下文)=>LoadingScreen(),
“/index”:(上下文)=>MainScreen(),
“/search”:(上下文)=>SearchScreen(),
};
WidgetBuilder=路由[routeSettings.name];
返回MaterialPackageRoute(生成器:(上下文)=>builder(上下文));
},
),
);
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振旋转套件/颤振旋转套件.省道”;
导入“包:climat/services/geologitalHelper.dart”;
导入“包:climat/services/NetworkHelper.dart”;
导入“包:climat/utilities/constants.dart”;
类加载屏幕扩展StatefulWidget{
@凌驾
_LoadingScreenState createState()=>\u LoadingScreenState();
}
类加载Screenstate扩展状态{
未来的getWeatherData()异步{
地图坐标=等待GeolocatorHelper().getGeoData();
最终NetworkHelper NetworkHelper=NetworkHelper(
uri:
“$endPoint&lat=${坐标[“纬度”]}和lon=${坐标[“经度”]}”);
最终动态数据=等待networkHelper.getData();
返回wait Navigator.pushNamed(上下文“/index”,参数:data);
}
@凌驾
void initState(){
这是.getWeatherData();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“气候”),
),
正文:安全区(
儿童:中心(
孩子:斯宾基林(
颜色:Colors.redAccent,
),
),
),
);
}
}
导入“包装:颤振/材料.省道”;
导入“包:climat/services/WeatherHelper.dart”;
导入“包:climat/services/NetworkHelper.dart”;
导入“包:climat/utilities/constants.dart”;
类MainScreen扩展StatefulWidget{
@凌驾
_MainScreenState createState()=>\u MainScreenState();
}
类_MainScreenState扩展状态{
颜色背景色;
字符串cityName;
内部温度;
字符串状态;
字符串图像;
温度;
int最大温度;
室内湿度;
Future updateUI({String userInput=null})异步{
动态气象数据;
if(userInput==null){
weatherData=ModalRoute.of(context).settings.arguments;
}否则{
最终网络助手网络助手=
NetworkHelper(uri:“$endPoint&q=$userInput”);
weatherData=等待networkHelper.getData();
}
最终int weatherCode=weatherData[“weather”][0][“id”];
最终WeatherHelper WeatherHelper=WeatherHelper(
天气代码:天气代码,
);
设置状态(){
this.backgroundColor=weatherHelper.getBackgroundColor();
this.cityName=weatherData[“name”];
this.temperature=weatherData[“main”][“temp”].toInt();
this.status=weatherHelper.getWeatherStatus();
this.minTemperature=weatherData[“main”][“temp_min”].toInt();
this.maxtempture=weatherData[“main”][“temp_max”].toInt();
this.湿度=天气数据[“主”][“湿度”];
this.image=weatherHelper.getWeatherImage();
});
}
@凌驾
void initState(){
这个。updateUI();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景色:这个,
appBar:appBar(
标题:文本(“气候”),
),
正文:安全区(
儿童:中心(
子:列(
mainAxisSize:mainAxisSize.min,
儿童:[
正文(
这个.cityName,
样式:TextStyle(
字体大小:24.0,
颜色:颜色,白色,
),
),
大小盒子(
身高:30.0,
),
划船(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
影像资产(
“/assets/images/${this.image}”,
比例:4.0,
),
大小盒子(
宽度:30.0,
),
正文(
“${this.temperature}°C”,
样式:TextStyle(
字体大小:96.0,
颜色:颜色,白色,
),
),
],
),
大小盒子(
身高:30.0,
),
正文(
this.status.toUpperCase(),
样式:TextStyle(
字体大小:24.0,
颜色:颜色,白色,
),
),
大小盒子(
身高:10.0,
),
正文(
“最小值/最大值:${this.mintTemperature.toString()}/${this.maxTemperature.toString()}”,
样式:TextStyle(
字体大小:24.0,
颜色:颜色,白色,
),
),
大小盒子(
身高:10.0,
),
T
import "package:flutter/material.dart";
import "package:flutter_spinkit/flutter_spinkit.dart";
import "package:climat/services/GeolocatorHelper.dart";
import "package:climat/services/NetworkHelper.dart";
import "package:climat/utilities/constants.dart";
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
Future<void> getWeatherData() async {
Map<String, double> coordinates = await GeolocatorHelper().getGeoData();
final NetworkHelper networkHelper = NetworkHelper(
uri:
"$endPoint&lat=${coordinates["latitude"]}&lon=${coordinates["longitude"]}");
final dynamic data = await networkHelper.getData();
return await Navigator.pushNamed(context, "/index", arguments: data);
}
@override
void initState() {
this.getWeatherData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Climat"),
),
body: SafeArea(
child: Center(
child: SpinKitRing(
color: Colors.redAccent,
),
),
),
);
}
}
import "package:flutter/material.dart";
import "package:climat/services/WeatherHelper.dart";
import "package:climat/services/NetworkHelper.dart";
import "package:climat/utilities/constants.dart";
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
Color backgroundColor;
String cityName;
int temperature;
String status;
String image;
int minTemperature;
int maxTemperature;
int humidity;
Future<void> updateUI({String userInput = null}) async {
dynamic weatherData;
if (userInput == null) {
weatherData = ModalRoute.of(context).settings.arguments;
} else {
final NetworkHelper networkHelper =
NetworkHelper(uri: "$endPoint&q=$userInput");
weatherData = await networkHelper.getData();
}
final int weatherCode = weatherData["weather"][0]["id"];
final WeatherHelper weatherHelper = WeatherHelper(
weatherCode: weatherCode,
);
setState(() {
this.backgroundColor = weatherHelper.getBackgroundColor();
this.cityName = weatherData["name"];
this.temperature = weatherData["main"]["temp"].toInt();
this.status = weatherHelper.getWeatherStatus();
this.minTemperature = weatherData["main"]["temp_min"].toInt();
this.maxTemperature = weatherData["main"]["temp_max"].toInt();
this.humidity = weatherData["main"]["humidity"];
this.image = weatherHelper.getWeatherImage();
});
}
@override
void initState() {
this.updateUI();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: this.backgroundColor,
appBar: AppBar(
title: Text("Climat"),
),
body: SafeArea(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
this.cityName,
style: TextStyle(
fontSize: 24.0,
color: Colors.white,
),
),
SizedBox(
height: 30.0,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"./assets/images/${this.image}",
scale: 4.0,
),
SizedBox(
width: 30.0,
),
Text(
"${this.temperature}°C",
style: TextStyle(
fontSize: 96.0,
color: Colors.white,
),
),
],
),
SizedBox(
height: 30.0,
),
Text(
this.status.toUpperCase(),
style: TextStyle(
fontSize: 24.0,
color: Colors.white,
),
),
SizedBox(
height: 10.0,
),
Text(
"MIN / MAX : ${this.minTemperature.toString()} / ${this.maxTemperature.toString()}",
style: TextStyle(
fontSize: 24.0,
color: Colors.white,
),
),
SizedBox(
height: 10.0,
),
Text(
"HUMIDITY : ${this.humidity}%",
style: TextStyle(
fontSize: 24.0,
color: Colors.white,
),
),
SizedBox(
height: 30.0,
),
ElevatedButton(
onPressed: () async {
dynamic userInput =
await Navigator.pushNamed(context, "/search");
this.updateUI(
userInput: userInput.toString(),
);
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 16.0,
),
),
child: Text(
"Search by city name",
style: TextStyle(
fontSize: 20.0,
),
),
),
],
),
),
),
);
}
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await this.getWeatherData();
setState(() { });
});
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await this.updateUI();
setState(() { });
});
}