如何在连接到 api 或使用 <T>StreamProvider.value() 获取数据时显示微光



我有这个简单的小部件。我想在客户端仍在获取或连接到 API 时有一个微光。

这是我正在挣扎的情况。我已经创建了微光小部件。在客户端完成获取/连接后,如果没有找到英雄,希望显示一个文本供客户端添加新英雄,如下所示。

class HeroesHomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<List<Hero>>.value(
value: //...db_fetch_here...
),
//...other providers
],
child: HeroesScreen()
)
}
}
class HeroesScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final heroes = Provider.of<List<Hero>>(context, listen: false) ?? [];
if(heroes.length <= 0) return Text('No heroes yet. Tap here to add');
// Not sure where or what condition should I write 
// to show shimmer while client still fetching data
// or client still connecting to api
return SomeWidget();
}
}
class Hero {
String id;
String name;
}

嗨,根据文档,不希望使用StreamProvider.Value传递值。特别是当值容易发生变化时。在此处查看文档。您可以提供一个初始值,然后按如下所示进行处理。

class HeroesHomeScreen extends StatelessWidget {
Stream<List<Hero>> getHeroes(BuildContext context) async* {
//do a db fetch here
List<Hero> heroes = [
Hero()
..id = '1'
..name = 'IronMan',
Hero()
..id = '2'
..name = 'CaptainAmerica',
];
await Future.delayed(Duration(seconds: 5)); // simulate a delay.
yield heroes;
}
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
StreamProvider<List<Hero>>(
create: getHeroes,
initialData: null,
),
//...other providers
],
child: HeroesScreen(),
);
}
}

相反,您可以检查传递给使用者小部件的数据,如下所示,并决定要呈现的内容。在这里,我正在检查列表是否为空并显示循环进度指示器。

class HeroesScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
alignment: Alignment.center,
child: Consumer<List<Hero>>(
builder: (context, List<Hero> heroes, child) {
if (heroes == null)
// replace the return with your shimmer widget
return Card(child: CircularProgressIndicator());
return ListView.builder(
itemCount: heroes.length,
itemBuilder: (context, index) {
return Card(
child: Text('My hero is hero ${heroes[index].name}'),
);
},
);
},
),
);
}
}

最新更新