【问题标题】:Avoid rebuilding of children while scrolling in SliverGrid in flutter在颤动中滚动 SliverGrid 时避免重建子项
【发布时间】:2020-09-07 06:04:22
【问题描述】:

您好,我在 CustomScrollView 中使用以下代码来使用 SliverGridSliverChildBuilderDelegate 在网格中显示图像。在快速滚动时,已经缓存图像的子小部件在离开屏幕时会被破坏,并在它们在屏幕上时重建。如何避免他们在卷轴上摧毁和重建它们?

    SliverGrid(
            gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 150,
              childAspectRatio: 1 / 1,
              crossAxisSpacing: 4.0,
              mainAxisSpacing: 4.0,
            ),
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return ClipRRect(
                    borderRadius: BorderRadius.circular(5.0),
                    child: Container(
                      alignment: Alignment.bottomRight,
                      padding: EdgeInsets.all(10.0),
                      decoration: BoxDecoration(
                        image: DecorationImage(
                          fit: BoxFit.fill,
                          image: CachedNetworkImageProvider(
                            "https://source.unsplash.com/${150}/${150 + index}/",
                          ),
                        ),
                      ),
                      child: index == (index / 2) + 1
                          ? Icon(
                              Icons.burst_mode,
                              color: AppTheme.fullWhite,
                            )
                          : index == (index / 6)
                              ? Icon(
                                  Icons.play_circle_filled,
                                  color: AppTheme.fullWhite,
                                )
                              : Container(),
                    ));
              },
              childCount: childCount,
            ),
          )

注意:如果我删除了图片 url 中的索引,那么在快速滚动时它会很快加载,因为它显示的是相同的图片。

https://source.unsplash.com/${150}/${150 + 索引}/

【问题讨论】:

    标签: flutter flutter-sliver sliver-grid


    【解决方案1】:

    我不知道您是否找到了答案,但这两个选项对我有用: cacheExtent,shrinkWrap 为假。您可以使 cacheExtent 或多或少。我敢肯定,如果它太多,它会消耗太多内存,因为列表生成器会在构建和销毁时为您管理内存。

    CustomScrollView(
        cacheExtent: 3500,
        shrinkWrap: false,
        controller: _scrollController,
        slivers: <Widget>[
          SliverGrid(
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3,
              mainAxisSpacing: 1.5,
              crossAxisSpacing: 1.5,
              childAspectRatio: 0.7,
            ),
    

    【讨论】:

      【解决方案2】:

      使用包装类概念。这是一个冗长的解决方案。但是您可以根据自己的需要进行自定义以使其更短。

          Widget decorationImage() {
              return DecorationImage(
                  fit: BoxFit.fill,
                  image: CachedNetworkImageProvider(
                  "https://source.unsplash.com/${150}/${150 + index}/",
                  );
          }
      

      包装类:

      class CustomSliverGrid extends StatelessWidget {
        Widget _widget;
        CustomSliverGrid(this._widget);
      
        @override
        Widget build(BuildContext context) {
          return SliverGrid(
            gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 150,
              childAspectRatio: 1 / 1,
              crossAxisSpacing: 4.0,
              mainAxisSpacing: 4.0,
            ),
            delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                return ClipRRect(
                    borderRadius: BorderRadius.circular(5.0),
                    child: Container(
                      alignment: Alignment.bottomRight,
                      padding: EdgeInsets.all(10.0),
                      decoration: BoxDecoration(
                        image: _widget,
                      ),
                      child: index == (index / 2) + 1
                          ? Icon(
                        Icons.burst_mode,
                        color: AppTheme.fullWhite,
                      )
                          : index == (index / 6)
                          ? Icon(
                        Icons.play_circle_filled,
                        color: AppTheme.fullWhite,
                      )
                          : Container(),
                    ));
              },
              childCount: childCount,
            ),
          );
        } 
      }
      

      在您的代码中使用该类:

      class YourWidgetPlace extends StatelessWidget {
      
          Widget decorationImage() {
            return DecorationImage(
                fit: BoxFit.fill,
                image: CachedNetworkImageProvider(
                "https://source.unsplash.com/${150}/${150 + index}/",
            );
          } 
          
          @override
          Widget build(BuildContext context) {
            return CustomSliverGrid(decorationImage());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-07-25
        • 1970-01-01
        • 2020-12-15
        • 2023-01-19
        • 1970-01-01
        • 1970-01-01
        • 2020-05-02
        • 2014-09-11
        • 1970-01-01
        相关资源
        最近更新 更多