GridView和CachedNetworkImage-滚动时重新加载图像

时间:2020-08-22 16:14:57

标签: flutter dart

我从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),
        ),
      ),
    );
  }
}

0 个答案:

没有答案