好的,我在使用FutureProvider时会遇到这个问题。
我已经在MaterialApp上方创建了FutureProvider,所以应该正确识别它?
我的小部件树有点像这样:
MyApp >> Home >> CardVehicle
这是我的main.dart代码,在其中创建对象提供程序:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final Service service = Service();
@override
Widget build(BuildContext context) {
return FutureProvider(
create: (_) => service.fetchCarYear(),
catchError: (_, error) => print(error),
child: MaterialApp(
title: 'KPM Demo',
theme: ThemeData(
primarySwatch: Colors.amber,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Home(),
),
);
}
}
我的虚拟服务类:
class Service {
Future<CarYear> fetchCarYear() async {
CarYear carYear = CarYear();
final response = await Future.delayed(
Duration(milliseconds: 500),
() => jsonEncode({
"data": [
{"year": "2020"},
{"year": "2019"},
{"year": "2018"}
]
}),
);
carYear = CarYear.fromJson(jsonDecode(response));
return carYear;
}
}
在这里放置我的提供者:
class CardVehicle extends StatelessWidget {
@override
Widget build(BuildContext context) {
CarYear carYear = Provider.of<CarYear>(context);
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
child: Column(
children: <Widget>[
DropdownButton(
isExpanded: true,
icon: Icon(Icons.keyboard_arrow_down),
items: carYear.data
.map((item) => DropdownMenuItem(child: Text(item.year)))
.toList() ?? null,
onChanged: null,
),
],
),
);
}
}
我在某个地方犯了错误吗?请帮忙!
编辑:这是我的CarYear课:
class CarYear {
List<Data> data;
CarYear({this.data});
CarYear.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
String year;
Data({this.year});
Data.fromJson(Map<String, dynamic> json) {
year = json['year'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['year'] = this.year;
return data;
}
}
答案 0 :(得分:0)
最好与ChangeNotifierProvider一起使用
在使用MultiProvider创建的主文件中
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => Service()),
],
child: MaterialApp(..)
)
}
在我添加的extends ChangeNotifiere
服务类中
notifyListeners()
通话时,所有使用者均会更新
class Service extends ChangeNotifier {
// Variable set in Service
CarYear _carYear = new CarYear();
CarYear get carYear => _carYear;
// init MultiProvider create() =>
Service() {
fetchCarYear();
}
Future<CarYear> fetchCarYear() async {
_carYear = CarYear();
final response = await Future.delayed(
Duration(milliseconds: 500),
() => jsonEncode({
"data": [
{"year": "2020"},
{"year": "2019"},
{"year": "2018"}
]
}),
);
// update _carYear Variable
_carYear = CarYear.fromJson(jsonDecode(response));
// all Consumer get a refresh()
notifyListeners();
}
}
在CardVehicle中,我放置了一个Consumer,但是CarYear carYear = Provider.of<Service>(context).carYear
也可以工作。
但是使用Provider.of,您每notifyListeners()
都会更新整个小部件
class CardVehicle extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
child: Column(
children: <Widget>[
// its better you do it here with a Consumer, because not the whole widget is updating
new Consumer<Service>(
builder: (context, service, child) => new DropdownButton(
isExpanded: true,
icon: Icon(Icons.keyboard_arrow_down),
items: service.carYear.data
.map((item) => DropdownMenuItem(child: Text(item.year), value: item.year,))
.toList(),
onChanged: (value) {
print(value);
},
),
),
],
),
);
}
}
答案 1 :(得分:0)
Comming from the other question you posted.
您需要更改catchError
中的futureProvider
,以返回 CarYear 而不是void。现在futureProvider
的类型为Dynamic,而provider.of
的搜索对象不是 dynamic 的提供者,而是 CarYear 的提供者。
为避免这种情况,请使catchError
返回一个空的CarYear或使其引发异常。
我希望这会有所帮助!
答案 2 :(得分:0)
仅适用于FutureProvider的示例
MultiProvider(
providers: [
FutureProvider(create: (_) => Service().fetchCarYear()),
],
child: MaterialApp(..)
返回CarYear的服务类
class Service {
// Variable set in Service
CarYear _carYear;
Future<CarYear> fetchCarYear() async {
_carYear = CarYear(data: new List());
final response = await Future.delayed(
Duration(milliseconds: 500),
() => jsonEncode({
"data": [
{"year": "2020"},
{"year": "2019"},
{"year": "2018"}
]
}),
);
// update _carYear Variable
_carYear = CarYear.fromJson(jsonDecode(response));
// all Consumer get a refresh()
//notifyListeners();
return _carYear;
}
}
和带有CarYear carYear = Provider.of<CarYear>(context);
的CardVehicle
class CardVehicle extends StatelessWidget {
@override
Widget build(BuildContext context) {
CarYear carYear = Provider.of<CarYear>(context);
return Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
child: Column(
children: <Widget>[
new DropdownButton(
isExpanded: true,
icon: Icon(Icons.keyboard_arrow_down),
items: carYear != null ? carYear.data
.map((item) => DropdownMenuItem(child: Text(item.year), value: item.year,))
.toList() : null,
onChanged: (value) {
print(value);
},
),
],
),
);
}
}