SliverAppBar:如何在滚动过程中保持本机视图有效?

时间:2019-01-21 10:07:02

标签: flutter

我想在SliverAppBar的flexibleSpace中显示本机视图(HeaderContainer),并阻止其重建。

return new Scaffold(
    body: CustomScrollView(
        slivers: <Widget>[
            SliverAppBar(
                backgroundColor: Colors.teal,
                pinned: true,
                expandedHeight: 180,
                flexibleSpace: FlexibleSpaceBar(
                    background: HeaderContainer(),
                    // HeaderContainer is a native View (AndroidView)
                ),
             ),
             SliverList(
                delegate: SliverChildListDelegate([content]),
            )
        ]
    )
);

不幸的是,HeaderContainer()在滚动过程中不可见时被破坏。
HeaderContainer()的创建非常昂贵,并且花费了一些时间。

是否有可能将此小部件保留在内存中并防止其在滚动时被破坏?

更新:

回滚后重建HeaderContaienr的问题仅是原生视图(例如AndroidView)的问题。


一些调查:

FlexibleSpaceBar使用以下行添加子项:

@override
Widget build(BuildContext context) {
    ...
    if (opacity > 0.0) {    <-- !
        children.add( ... );
    }

因此,仅当不透明度大于零时才将子级添加到树中,如果不透明度为零则将其删除(并销毁)。向后滚动会导致重建。

我最终遇到了一个自定义的flexibleSpace小部件,该小部件始终将孩子添加到视图树中。

1 个答案:

答案 0 :(得分:0)

每次setState,您的小部件树都会重建以匹配任何更改。每次滚动时,都需要渲染一个新的帧,因此您要抱怨的性能。您会想到3个选择:

1。您可能想在const上使用HeaderContainer构造函数

2。您可以尝试将HeaderContainer分配为的最终变量     您的build方法,以便仅重建     更改当前小部件实例是否保持不变,例如:

@override
Widget build(BuildContext context) {
  final header = HeaderContainer();

  return new Scaffold(
    body: CustomScrollView(
        slivers: <Widget>[
            SliverAppBar(
                backgroundColor: Colors.teal,
                pinned: true,
                expandedHeight: 180,
                flexibleSpace: FlexibleSpaceBar(
                    background: header,
                ),
             ),
                   SliverList(
                   delegate: SliverChildListDelegate([content]),
               )
           ]
       )
  );

3。或者您可以将此header添加为有状态窗口小部件的属性     但请记住,这将中断该小部件的热重装     (标题)。