如何从flutter中从异步任务中检索到的数据中将图像加载到卡片中?
Posted
技术标签:
【中文标题】如何从flutter中从异步任务中检索到的数据中将图像加载到卡片中?【英文标题】:How to load image to the Card from data retrieved from async task in flutter? 【发布时间】:2019-11-09 19:15:15 【问题描述】:我是 Flutter 开发的新手。我需要根据通过异步任务加载的数据将图像加载到卡中。
我有一个异步任务,它返回从 sqlite 本地数据库中查询的 Future> 用户数据。使用检索到的数据,我构建了一个 ListView 来显示使用 Card 的用户。但是在卡片内部,我试图显示一个图像,该图像将从 Firebase 存储中下载,具体取决于从本地数据库中检索到的数据。但图像 URL 为空。
Widget build(BuildContext context)
var allCards = DBProvider.db.getAllCards();
return FutureBuilder<List<User>>(
future: DBProvider.db.getAllCards(),
builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot)
if (snapshot.hasError) return new Text('Error: $snapshot.error');
switch (snapshot.connectionState)
case ConnectionState.waiting:
return new Text('Loading...');
default:
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index)
User user = snapshot.data[index];
return Card(
elevation: 8.0,
margin:
new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
child: Image(
image: CachedNetworkImageProvider(FirebaseStorage().ref().child('employer_logo').child('00001').child('google-banner.jpg').getDownloadURL().toString()),
fit: BoxFit.cover,
),
),
Positioned(
bottom: 0,
left: 0,
child: Container(
padding: EdgeInsets.all(10),
child: Text(
'Google Incorperation',
style: TextStyle(
fontSize: 20, color: Colors.white),
),
),
)
],
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
),
child: ListTile(
title: Text(user.fname + " " + user.lname,
style: TextStyle(
color: Colors.blue[400], fontSize: 20)),
subtitle: Text(user.designation,
style: TextStyle(
color: Colors.blue[300], fontSize: 16)),
onTap: () =>
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Profile(
user.fname,
user.lname,
user.uid,
user.designation,
user.mobile,
user.employerId)))
,
),
)
],
),
);
,
);
,
);
我希望显示从 firebase 存储下载的图像
【问题讨论】:
【参考方案1】:这将是我的第一个答案,这里可能有很多方法可以改进我的答案。但我会试一试:实际上,您将不得不在Futures 和Streams 上查找很多内容,因为它在许多应用程序中都是相当重要的一部分。如果您的应用程序需要 Web 上的任何内容,它将需要 Futures,或者它是更大的对应 Stream。在这种情况下,如果您想设置一个可能包含多个图像的 Listview,我会选择 Stream。此外,我会将所有数据库逻辑保存在一个单独的文件中。但是,如果您现在不想过多修改代码,我会使用FutureBuilder。 我已经看到您已经在代码中使用了其中一个。但在这种情况下,请使用:
...
int maxsize = 10e6.round(); // This is needed for getData. 10e^6 is usually big enough.
return new Card (
FutureBuilder<UInt8List> ( // I also think getting Data, instead of a DownloadUrl is more practical here. It keeps the data more secure, instead of generating a DownloadUrl which is accesible for everyone who knows it.
future: FirebaseStorage().ref().child('entire/path/can/go/here')
.getData(maxsize),
builder: (BuildContext context, AsyncSnapshot<UInt8List> snapshot)
// When this builder is called, the Future is already resolved into snapshot.data
// So snapshot.data contains the not-yet-correctly formatted Image.
return Image.memory(data, fit: BoxFit.Cover);
,
),
【讨论】:
我能够根据我的情况应用您的解决方案。多谢。这节省了我几天的挣扎。如果有人想知道,我会发布我的代码。【参考方案2】:Widget build(BuildContext context)
var allCards = DBProvider.db.getAllCards();
return FutureBuilder<List<User>>(
future: DBProvider.db.getAllCards(),
builder: (BuildContext context, AsyncSnapshot<List<User>> snapshot)
if (snapshot.hasError) return new Text('Error: $snapshot.error');
switch (snapshot.connectionState)
case ConnectionState.waiting:
return new Text('Loading...');
default:
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index)
User user = snapshot.data[index];
int maxsize = 10e6.round();
return Card(
elevation: 8.0,
margin:
new EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
child: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
child: FutureBuilder<dynamic>(
future: FirebaseStorage()
.ref()
.child('employer_logo')
.child('00001')
.child('google-banner.jpg')
.getDownloadURL(),
builder: (BuildContext context,
AsyncSnapshot<dynamic> snapshot)
if (snapshot.connectionState !=
ConnectionState.waiting)
return Image(
image: CachedNetworkImageProvider(
snapshot.data.toString()),
fit: BoxFit.cover,
);
else
return Text('Loading image....');
,
),
),
Positioned(
bottom: 0,
left: 0,
child: Container(
padding: EdgeInsets.all(10),
child: Text(
'Google Incorperation',
style: TextStyle(
fontSize: 20, color: Colors.white),
),
),
)
],
),
Container(
decoration: BoxDecoration(
color: Colors.white10,
),
child: ListTile(
title: Text(user.fname + " " + user.lname,
style: TextStyle(
color: Colors.blue[400], fontSize: 20)),
subtitle: Text(user.designation,
style: TextStyle(
color: Colors.blue[300], fontSize: 16)),
onTap: () =>
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Profile(
user.fname,
user.lname,
user.uid,
user.designation,
user.mobile,
user.employerId)))
,
),
)
],
),
);
,
);
,
);
【讨论】:
以上是关于如何从flutter中从异步任务中检索到的数据中将图像加载到卡片中?的主要内容,如果未能解决你的问题,请参考以下文章
如何在flutter中将标记从firebase(真实数据库)检索到新的google maps api
如何将通过 Timer.periodic 从 API 检索到的数据集成到 Flutter Cubit 项目中