一些滚动后颤动ListView KeepAlive

Posted

技术标签:

【中文标题】一些滚动后颤动ListView KeepAlive【英文标题】:flutter ListView KeepAlive after some scroll 【发布时间】:2019-03-03 14:46:25 【问题描述】:

我想keepAlive 我的小部件已经在ListView 中呈现。我尝试使用ListView 类提供的addAutomaticKeepAlives:true 属性。

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

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 ,
);

【问题讨论】:

【参考方案1】:

如果您想保留一个条子列表(用于 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,
        // ),
      ),
   ],
);

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

【讨论】:

【参考方案2】:

如 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;

【讨论】:

super.build(context); 真的解决了我的问题。谢谢 "方法'build'在超类型中总是抽象的" ^ 我得到了同样的结果。您似乎无法再从 State 调用此方法...【参考方案3】:

要使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;

【讨论】:

这适用于图像吗?我试过了,但是当我滚动时,图像仍然会重新渲染。如果那个时候慢慢滚动就没有问题。但在快速滚动的图像小部件中重新渲染。 嗨,你能帮忙吗?我在使用 CustomScrollView 和 SliverList 时遇到了类似的问题……我有一个 WebView,当页面滚动时会不断重新加载……我的 CustomScrollView 上有足够高的 cacheExtent。我还具备所有先决条件,例如:super.build(context);bool get wantKeepAlive 覆盖...我还设置了AutomaticKeepAliveClientMixin...不知道发生了什么,但 WebView 绝对不会重新加载类似SingleChildScrollView.. 所以我猜是 CustomScrollView/SliverList 正在破坏它..【参考方案4】:

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

【讨论】:

以上是关于一些滚动后颤动ListView KeepAlive的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中使我的文本与 listview.builder 一起滚动

如何使我的 ListView 在颤动中可滚动?

颤动中滚动视图内的Listview

颤动 ListView 滚动到索引不可用

在listview中颤动Custompaint:忽略两个手指滚动

Listview在颤动中强制滚动到顶部