Flutter - 方法'|'被调用为空。热重载后它正在工作
Flutter - The method '|' was called on null. After hot reload it is working
我是 flutter 的新手。我不知道后台发生了什么,因为热重载后它工作正常。在发生的另一个 dart 文件中,firebase 没有在热重载后立即向我提供有关初始化的数据。
class CityServices {
getCites() {
return Firestore.instance.collection('cities').getDocuments();
}
}
class _HomeScreenState extends State<HomeScreen> {
bool citiesFlag = false;
var cities;
int citiesCount;
String actualCity;
可能是这里出错了
@override
void initState() {
super.initState();
CityServices().getCites().then((QuerySnapshot) {
if (QuerySnapshot.documents.isNotEmpty) {
citiesFlag = true;
cities = QuerySnapshot.documents;
citiesCount = QuerySnapshot.documents.length;
}
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: MyColors.vintageGreen,
appBar: AppBar(
backgroundColor: MyColors.background,
title: Center(
child: Text(
'Válasszon települést...',
style: GoogleFonts.barlowCondensed(
color: MyColors.appbarText,
fontSize: 26.0,
fontWeight: FontWeight.w500),
),
),
),
body: Center(
child: Container(
child: GridView.count(
crossAxisCount: 2,
children: List.generate(citiesCount, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: InkWell(
onTap: () {
actualCity = cities[index]['city_name'];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CityView(cityName: actualCity)),
);
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Center(
child: Text(
cities[index]['city_name'],
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18.0),
)),
subtitle: Center(child: Text('22 bejegyzés')),
),
Flexible(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5)),
child: Padding(
padding: EdgeInsets.only(bottom: 15.0),
child: Image(
image: AssetImage(
cities[index]['img_path'],
),
),
),
),
)
],
),
),
color: MyColors.background,
);
}),
),
),
),
),
);
}
}
也许这里是错误的?它应该在飞镖文件之上吗?
class HomeScreen extends StatefulWidget {
static const String id = 'home';
@override
_HomeScreenState createState() => new _HomeScreenState();
}
让我解释一下问题及其发生的原因,然后提出一些解决方案。
在 initState
中,您正在调用 CityServices().getCites().then...
,这是一个 async
方法。
但是,当您第一次构建小部件时,您期望从 Firestore 获得的数据还没有准备好,因此您得到 cities
和 citiesCount
的 null
。
短期解决方案:
确保有空检查,等待数据时显示指示器。
body: Center(
child: (cities == null) ?
CircularProgressIndicator()
: Container(...
此外,您还可以将 initState
重构为类似这样的东西
void getCities() async {
var snapshot CityServices().getCites();
setState(() {
citiesFlag = true;
cities = snapshot.documents;
citiesCount = snapshot.documents.length;
});
}
@override
void initState() {
getCities();
super.initState();
}
长期解决方案:
使用 BLoC
模式并使数据加载与 UI.
分离
请参阅 flutter_bloc 了解如何实施。
我是 flutter 的新手。我不知道后台发生了什么,因为热重载后它工作正常。在发生的另一个 dart 文件中,firebase 没有在热重载后立即向我提供有关初始化的数据。
class CityServices {
getCites() {
return Firestore.instance.collection('cities').getDocuments();
}
}
class _HomeScreenState extends State<HomeScreen> {
bool citiesFlag = false;
var cities;
int citiesCount;
String actualCity;
可能是这里出错了
@override
void initState() {
super.initState();
CityServices().getCites().then((QuerySnapshot) {
if (QuerySnapshot.documents.isNotEmpty) {
citiesFlag = true;
cities = QuerySnapshot.documents;
citiesCount = QuerySnapshot.documents.length;
}
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: MyColors.vintageGreen,
appBar: AppBar(
backgroundColor: MyColors.background,
title: Center(
child: Text(
'Válasszon települést...',
style: GoogleFonts.barlowCondensed(
color: MyColors.appbarText,
fontSize: 26.0,
fontWeight: FontWeight.w500),
),
),
),
body: Center(
child: Container(
child: GridView.count(
crossAxisCount: 2,
children: List.generate(citiesCount, (index) {
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: InkWell(
onTap: () {
actualCity = cities[index]['city_name'];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
CityView(cityName: actualCity)),
);
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Center(
child: Text(
cities[index]['city_name'],
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18.0),
)),
subtitle: Center(child: Text('22 bejegyzés')),
),
Flexible(
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5)),
child: Padding(
padding: EdgeInsets.only(bottom: 15.0),
child: Image(
image: AssetImage(
cities[index]['img_path'],
),
),
),
),
)
],
),
),
color: MyColors.background,
);
}),
),
),
),
),
);
}
}
也许这里是错误的?它应该在飞镖文件之上吗?
class HomeScreen extends StatefulWidget {
static const String id = 'home';
@override
_HomeScreenState createState() => new _HomeScreenState();
}
让我解释一下问题及其发生的原因,然后提出一些解决方案。
在 initState
中,您正在调用 CityServices().getCites().then...
,这是一个 async
方法。
但是,当您第一次构建小部件时,您期望从 Firestore 获得的数据还没有准备好,因此您得到 cities
和 citiesCount
的 null
。
短期解决方案:
确保有空检查,等待数据时显示指示器。
body: Center(
child: (cities == null) ?
CircularProgressIndicator()
: Container(...
此外,您还可以将 initState
重构为类似这样的东西
void getCities() async {
var snapshot CityServices().getCites();
setState(() {
citiesFlag = true;
cities = snapshot.documents;
citiesCount = snapshot.documents.length;
});
}
@override
void initState() {
getCities();
super.initState();
}
长期解决方案:
使用 BLoC
模式并使数据加载与 UI.
分离
请参阅 flutter_bloc 了解如何实施。