我尝试了ChangeNotifierProvider
的多个实现(final xyz=provider.of<DigitalHeroes>(context)
、Consumer<DigitalHeroes>
..(,但无法在侦听器/消费者中收到更新的列表。它总是返回一个空列表。
I/flutter ( 4410): []
在我的启动屏幕中,我从providers/digital_heroes.dart调用DigitalHeroes().getHeroes()
。它调用函数并打印cms中新英雄列表的长度为1,所以我知道_heroes
列表正在provider类中更新。
以下是现有的实施情况。
型号/digital_hero.dart
class DigitalHero {
String name;
String title;
String title_extended;
String phone_number;
String email_address;
double location_lat;
double location_long;
String image;
String bio;
Map<String, dynamic> related_projects;
DigitalHero({
this.name,
this.title,
this.title_extended,
this.phone_number,
this.email_address,
this.location_lat,
this.location_long,
this.image,
this.bio,
this.related_projects,
});
static DigitalHero fromJson(Map<String, dynamic> json) {
return DigitalHero(
name: json['name'] as String,
title: json['title'] as String,
title_extended: json['title_extended'] as String,
phone_number: json['phone_number'] as String,
email_address: json['email_address'] as String,
location_lat: json['location_lat'] as double,
location_long: json['location_long'] as double,
image: json['image'] as String,
bio: json['bio'] as String,
related_projects: json['related_projects'] as Map<String, dynamic>,
);
}
Map<String, dynamic> toJson() => {
'name': name,
'title': title,
'title_extended': title_extended,
'phone_number': phone_number,
'email_address': email_address,
'location_lat': location_lat,
'location_long': location_long,
'image': image,
'bio': bio,
'related_projects': related_projects,
};
}
providers/digital_heroes.dart:
class DigitalHeroes with ChangeNotifier {
var singleton = Singleton();
List<DigitalHero> _heroes = [];
List<DigitalHero> get heroes {
return [..._heroes];
}
void getHeroes() async {
await singleton.init();
try {
var result = await singleton.contentChef
.getPreviewChannel(
apiKey: 'XYZ',
publishingChannel: 'XYZ',
status: PublishingStatus.stage,
)
.searchContents<DigitalHero>(
filters: SearchContentsFilters(
skip: 0,
take: 10,
contentDefinition: ['digital-hero'],
),
fromJson: DigitalHero.fromJson);
var json = jsonDecode(jsonEncode(result));
List<DigitalHero> heroes = [];
for (var item in json['items']) {
heroes.add(DigitalHero.fromJson(item['payload']));
}
_heroes = heroes;
print(_heroes.length); // prints 1, which is the correct length of the list of heroes from cms
notifyListeners();
} catch (e) {
print(e);
} finally {
//notifyListeners(); // also tried notifying here in case it was an async issue, list still empty
}
}
// void getHeroes() { //also tried this, list still empty
// _heroes = [
// DigitalHero(
// bio: "hi",
// name: "hi",
// email_address: "hi",
// image: "null",
// location_lat: 5)
// ];
// notifyListeners();
// }
}
屏幕/digital_heroes/digital_heros.art
class DigitalHeroesScreen extends StatefulWidget {
static const routeName = 'digital_heroes';
@override
_DigitalHeroesScreenState createState() => _DigitalHeroesScreenState();
}
class _DigitalHeroesScreenState extends State<DigitalHeroesScreen> {
var loading = false;
// var singleton = Singleton();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: Icon(
Icons.search,
color: Colors.black,
),
onPressed: () {
showSearch(
context: context,
delegate: CustomSearchDelegate(),
);
},
),
title: Text(
'Digital Heroes',
style: TextStyle(color: Colors.black),
),
actions: [
IconButton(
icon: Icon(
Icons.person,
color: Colors.black,
),
// color: Colors,
onPressed: () {
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(12.0)),
),
context: context,
builder: (context) {
return Container(
child: buildModalBottomProfile(),
);
});
},
)
],
),
body: HeroList(),
// ListView.builder(
// itemBuilder: (context, index) =>
// DigitalHeroItem(digitalHeroes.heroes[index]),
// itemCount: digitalHeroes.heroes.length,
// );
);
}
}
class HeroList extends StatelessWidget {
const HeroList({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final heroesData = Provider.of<DigitalHeroes>(context);
final heroes = heroesData.heroes; //calls get method in heroes provider
return InkWell(
child: Text("click to print provided list of heroes"),
onTap: () => {print(heroes)}, //prints empty list '[]'
);
}
}
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<DigitalHeroes>( //tried with multiprovider, no change
create: (ctx) => DigitalHeroes(),
child: MaterialApp(
title: 'xyz',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: MyHomePage(title: 'Home'),
routes: {
Splash.routeName: (ctx) => Splash(),
Onboarding.routeName: (ctx) => Onboarding(),
Login.routeName: (ctx) => Login(),
BottomTabsScreen.routeName: (ctx) => BottomTabsScreen(),
Home.routeName: (ctx) => Home(),
DigitalHeroesScreen.routeName: (ctx) => DigitalHeroesScreen(),
},
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
Singleton.instance.screenSize = MediaQuery.of(context).size;
return Container(
child: Padding(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: Splash(),
),
);
}
}
内部屏幕/splash.dart
void initData() async {
setState(() {
_loading = true;
});
// ignore: await_only_futures
await DigitalHeroes().getHeroes();
setState(() {
_loading = false;
});
if (!_loading && !_animating) {
Navigator.of(context).pushReplacementNamed(Onboarding.routeName);
}
}
我终于弄明白了。我用创建了一个新的数字英雄
await DigitalHeroes().getHeroes();
而不是像那样使用继承的实例
await Provider.of<DigitalHeroes>(context, listen: false).getHeroes();
或者像一样在提供者的构造函数中调用异步代码
class Heroes extends ChangeNotifier {
List _heroes;
void getData() async {
// Loading Assets
_heroes=heroes;
notifyListeners();
}
Heroes() {
getData();
}
}