一些滚动后,ListView KeepAlive颤动

NIR*_*TEL 2 listview flutter flutter-sliver flutter-layout

我想要keepAlive我已经呈现的小部件ListView.我尝试了addAutomaticKeepAlives:trueListView类提供的属性.

这是我使用的示例代码.SliverChildBuilderDelegate委托中提供的相同问题SliverList.

ListView.builder(
    itemBuilder: (context,index){
      return Card(
        child: Container(
          child: Image.asset("images/${index+1}.jpg",fit: BoxFit.cover,),
          height: 250.0,
        ),
      );
    },
    addAutomaticKeepAlives: true,
    itemCount:40 ,
);
Run Code Online (Sandbox Code Playgroud)

小智 14

正如 AutomaticKeepAliveClientMixin 和 Remi 的回答所述,

子类必须实现 wantKeepAlive,并且它们的构建方法必须调用 super.build(返回值将始终返回 null,应该被忽略)。

因此,将您的构建方法更改为:

class Foo extends StatefulWidget {
  @override
  FooState createState() {
    return new FooState();
  }
}

class FooState extends State<Foo> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Container(

    );
  }

  @override
  bool get wantKeepAlive => true;
}
Run Code Online (Sandbox Code Playgroud)

  • `super.build(context);` 确实解决了我的问题。谢谢 (2认同)

Rém*_*let 8

为了automaticKeepAlive工作,需要保持活动的每个项目必须发送特定通知.

触发此类通知的典型方法是使用AutomaticKeepAliveClientMixin

class Foo extends StatefulWidget {
  @override
  FooState createState() {
    return new FooState();
  }
}

class FooState extends State<Foo> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    return Container(

    );
  }

  @override
  bool get wantKeepAlive => true;
}
Run Code Online (Sandbox Code Playgroud)

  • 这对图像有用吗?我尝试过,但是在滚动时图像仍会重新渲染。如果那时候慢慢滚动,就没有问题了。但是在快速滚动的图像小部件中会重新渲染。 (2认同)

Jas*_*ott 6

您也可以尝试查看列表视图构建器上的 cacheExtent 属性。将其设置为覆盖您的项目的值将使它们保持活力。感谢上面的雷米。我不知道在列表中使用时需要 keepAlive 的项目 - 以前在 flutter doco 中没有......


小智 6

如果你想保持一个条子列表(对于 CustomScrollView),你需要做的就是使用 'SliverChildListDelegate' 而不是 'SliverChildBuilderDelegate'

这是我的代码:

final List<Product> products;
return CustomScrollView(
  controller: _scrollController,
    slivers: [
      _mySliverAppBar(context, title),
      SliverList(
        delegate: SliverChildListDelegate(
          List.generate(products.length, (index) => _myProductCard(context,products[index]))
        )
        // SliverChildBuilderDelegate(
        //   (context, index) => _myProductCard(context, products[index]),
        //   childCount: products.length,
        // ),
      ),
   ],
);
Run Code Online (Sandbox Code Playgroud)

正如你在代码中看到的,我之前使用的是 SliverChildBuilderDelegate