如何在flutter中使用precacheImage函数?

时间:2019-05-09 04:46:37

标签: caching flutter flutter-layout imagelist flutter-sliver

无法使用precacheImage函数将本地图像从资产加载并缓存到GridView或ListView中。

问题:滚动列表时,图像始终会重新加载。

class AppLandingPage extends StatelessWidget {
  final String title;

  AppLandingPage({Key key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        drawer: DrawerPage(),
        body: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return getToolbarWidget("Home title");
          },
          body: setDataToContainer(),
        ));
  }
}

Container setDataToContainer() {
  return Container(
    color: Colors.white,
    margin: EdgeInsets.only(left: 4.0, right: 4, bottom: 4, top: 4),
    child: CustomScrollView(
      slivers: <Widget>[
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 1"),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget("title", "key_x", "pnl.svg"),
              BodyWidget("title2", "key_x", "cls.svg"),
              BodyWidget(
                  "title3", "key_x", "irr.svg"),
              BodyWidget(
                  "title4", "key_x", "icp.svg"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Header 2"),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget("title5", "key_x", "ict.svg"),
              BodyWidget("title6", "key_x", "icc.svg"),
            ],
          ),
        ),
        SliverList(
          delegate: SliverChildListDelegate(
            [
              HeaderWidget("Others"),
            ],
          ),
        ),
        SliverGrid(
          gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
          delegate: SliverChildListDelegate(
            [
              BodyWidget("title7", "key_x", "icd.svg"),
              BodyWidget("title8", "6", "ici.svg"),
            ],
          ),
        ),
      ],
    ),
  );
}

class HeaderWidget extends StatelessWidget {
  final String text;

  HeaderWidget(this.text);

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(left: 10.0, right: 10, bottom: 2, top: 20),
      child: Text(
        text.toUpperCase(),
        style: TextStyle(
            color: hexToColor(themeColor1),
            fontSize: 16,
            fontWeight: FontWeight.bold),
      ),
      color: Colors.white,
    );
  }
}

class BodyWidget extends StatelessWidget {
  final String imagePath;
  final String title;
  final String navigationKey;

  BodyWidget(this.title, this.navigationKey, this.imagePath);

  @override
  Widget build(BuildContext context) {
    return Container(
        alignment: Alignment.center,
        child: Card(
          color: hexToColor(themeColor1),
          elevation: 5,
          child: InkWell(
            onTap: () {
              navigateToView(context, navigationKey);
            },
            child: Stack(
              children: <Widget>[
                Align(
                  alignment: Alignment.topCenter,
                  child: Container(
                    margin: EdgeInsets.only(top: 40),
                    child: SvgPicture.asset(
                      "assets/images/$imagePath",
                      color: Colors.white,
                      width: 35,
                      height: 35,
                    ),
                  ),
                ),
                Align(
                  alignment: Alignment.bottomCenter,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    verticalDirection: VerticalDirection.up,
                    children: <Widget>[
                      Container(
                        padding: EdgeInsets.all(10),
                        color: Colors.black.withOpacity(.2),
                        child: Text(
                          title,
                          style: TextStyle(
                              color: Colors.white,
                              fontSize: 14,
                              fontWeight: FontWeight.normal),
                        ),
                      )
                    ],
                  ),
                ),
              ],
            ),
          ),
        ));
  }

  void navigateToView(BuildContext context, String navigationKey) {

    Navigator.push(
      context,
      PageRouteBuilder(
        pageBuilder: (context, animation1, animation2) {
          return NewSections();
        },
        transitionsBuilder: (context, animation1, animation2, child) {
          return FadeTransition(
            opacity: animation1,
            child: child,
          );
        },
        transitionDuration: Duration(milliseconds: 600),
      ),
    );
  }
}

3 个答案:

答案 0 :(得分:0)

在您的BidyWidget中,您可以使用此方法并从此处像以下示例一样预缓存图像:

  @override
  void initState() {
  // adjust the provider based on the image type
  precacheImage(new AssetImage('...'));
  super.initState();
 }

可能重复:Preloading local image assets in Flutter

答案 1 :(得分:0)

与其在initState中调用precacheImage(),不应该这样:

Image myImage;

  @override
  void initState() {
    super.initState();
    myImage= Image.asset(path);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    precacheImage(myImage.image, context);
  }

答案 2 :(得分:0)

我不确定如何解决预加载问题。但是,您可以对状态小部件的状态类使用一个AutomaticKeepAliveClientMixin(包含网格对象的状态类。您必须将BodyWidget设置为StatefulWidget),以便您仅加载一次每个图像,而不必重新加载小部件超出可见性时呈现。

class _WidgetState extends State<Widget> with AutomaticKeepAliveClientMixin<Widget>{
….
….
@override
@mustCallSuper
Widget build(BuildContext context)….
….
….
@override
bool get wantKeepAlive => true;
}'

希望有帮助!