Flutter Pageview:以意外的方式在窗口小部件上向后滑动调用构建方法

时间:2018-12-29 14:06:10

标签: flutter

考虑这个简单的代码段,这是我为重现问题而编写的代码段。这只是一个包含3个有状态小部件的综合浏览量。 (它是独立的,您可以复制粘贴并运行它):

import 'package:flutter/material.dart';

void main() => runApp(new TestInherited());

class TestInherited extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Pageview test',
        home: PageView(
          children: <Widget>[TestWidget("1"), TestWidget("2"), TestWidget("3")],
        ));
  }
}

class TestWidget extends StatefulWidget {
  final String _name;
  String get name => _name;

  @override
  TestWidgetState createState() {
    return TestWidgetState();
  }

  TestWidget(this._name);
}

class TestWidgetState extends State<StatefulWidget> {
  @override
  Widget build(BuildContext context) {
    TestWidget w = widget;
    print("building ${w._name}");
    return Center(child: Text(w._name));
  }
}

从第1页切换至第2页至第3页时,您会看到构建方法被很好地调用(由于print语句)。 但是,当从第3页向后翻到第2页时,第2页不会发生这种情况,但是从2翻到第1页则称为第1页。 所以:

  • 3到2:什么都没发生
  • 2比1:打印“建筑物1”

这对我来说是个问题,因为在第3页的项目中,我更改了会影响第2页的内容,因此需要对其进行重建。

当只添加几页时(甚至有5页),它甚至变得更加奇怪。然后前进可以很好地工作(每页都进行打印),但是后退...

  • 5到4:打印“建筑物3”(??)
  • 4到3:没有
  • 3到2:打印“建筑物2”
  • 2比1:打印“建筑物1”

有人可以向我解释吗?

非常感谢您的时间和帮助!

1 个答案:

答案 0 :(得分:0)

作为一般规则,您应该假设,如果您不希望重建任何内容,则不会重建;如果您不希望重建所有内容,则应重建所有内容。该模型是我们每帧都重建所有内容,但是我们进行了优化以删除不需要证明的重建内容。

在这种情况下,由于您从不调用setState,因此我们实际上不需要重建任何内容。我们可能只重建不可见的小部件,以节省内存。

当需要重新构建时,TestWidget应该调用setState。您可以让第3页通过Listenable或类似方法将通知发送到第2页,并让第2页使用该通知来知道何时进行重建。