我从API获取项目列表,每个项目都包含一个图像,这些项目应显示在GridView中。我正在使用GridView.count进行构建,并使用CachedNetworkImage从网络加载图像。但是,当我滚动底部或顶部时,所有图像都会重新加载,从而产生滞后的体验。
图像实际上是ListItem的子级,ListItem是Stack小部件,它应该是ListItem的“背景”。 有没有人遇到同样的问题并找到了解决方案?我正在使用BLOC。
class PlayersPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return buildPlayersPage(context);
}
BlocConsumer buildPlayersPage(BuildContext context) {
return BlocConsumer(
cubit: BlocProvider.of<PlayersBloc>(context),
listener: (context, state) {
if (state is PlayersError) {
return DisplayEmptyState();
}
},
builder: _mapStateToPage,
);
}
Widget _mapStateToPage(context, state) {
if (state is PlayersInitial) {
return DisplayLoading();
} else if (state is PlayersLoading) {
return DisplayLoading();
} else if (state is PlayersLoaded) {
return DisplayPlayersGridView(state.players);
} else {
return DisplayEmptyState();
}
}
}
class DisplayPlayersGridView extends StatelessWidget {
final List<Player> players;
DisplayPlayersGridView(this.players);
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 8.0,
childAspectRatio: 0.9,
mainAxisSpacing: 8.0,
padding: EdgeInsets.all(8.0),
children: players.map((player) => TeamListItem(player)).toList());
}
}
class TeamListItem extends StatelessWidget {
final Player player;
TeamListItem(this.player);
@override
Widget build(BuildContext context) {
return GestureDetector(
child: Container(
child: Stack(
alignment: Alignment.topLeft,
children: [
PlayerImage(player.playerPictureOne),
NumberContainer(player.squadNumber),
SponsorRectangle(player.sponsoredBy),
PlayersDetailsContainer(player.playerName, player.position),
Positioned(
right: 16.0,
bottom: 16.0,
child: Image.asset(
ViewUtils.getCountryFlag(player.country.toLowerCase()),
package: 'country_icons',
width: 15,
height: 10,
fit: BoxFit.cover,
),
)
],
),
),
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PlayerDetailsPage(
player: player,
),
)),
);
}
}
class PlayersDetailsContainer extends StatelessWidget {
final String playerName;
final String position;
PlayersDetailsContainer(this.playerName, this.position);
@override
Widget build(BuildContext context) {
return Positioned(
left: 16.0,
bottom: 16.0,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
playerName,
style: TextStyle(fontSize: 13.0, color: Colors.white),
),
SizedBox(height: 4.0),
Text(position.toUpperCase(),
style: TextStyle(fontSize: 10.0, color: Colors.white))
],
),
);
}
}
class SponsorRectangle extends StatelessWidget {
final String sponsoredBy;
SponsorRectangle(this.sponsoredBy);
@override
Widget build(BuildContext context) {
return Positioned(
left: 30.0,
child: Container(
width: 100.0,
height: 15.0,
color: ColorsUtils.ACCENT_COLOR,
alignment: Alignment.center,
child: Text(
sponsoredBy,
style: TextStyle(fontSize: 8.0, color: Colors.white),
),
),
);
}
}
class NumberContainer extends StatelessWidget {
final String playerNumber;
NumberContainer(this.playerNumber);
@override
Widget build(BuildContext context) {
return Container(
width: 30.0,
height: 30.0,
alignment: Alignment.center,
color: Colors.black,
child: Text(
playerNumber,
style: TextStyle(fontSize: 15.0, color: Colors.white),
),
);
}
}
class PlayerImage extends StatelessWidget {
final String imageUrl;
PlayerImage(this.imageUrl);
@override
Widget build(BuildContext context) {
return CachedNetworkImage(
imageUrl: imageUrl,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(image: imageProvider, fit: BoxFit.cover),
),
),
);
}
}