导航到新路线时处理小部件

时间:2019-03-13 11:19:53

标签: dart flutter

我的应用程序中有两个屏幕。

屏幕A在打开时会执行计算量大的操作,并在调用dispose()时通过取消对数据库的动画/订阅来正确处理,以防止内存泄漏。

从屏幕A,您可以打开另一个屏幕(屏幕B)。

当我使用Navigator.pushNamed时,即使现在显示了屏幕B,屏幕A仍保留在内存中,并且dispose()没有被调用。

有没有办法在不可见的情况下强制丢弃屏幕A?

从不处理第一条路线的示例代码:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatefulWidget {
  @override
  _FirstRouteState createState() => _FirstRouteState();
}

class _FirstRouteState extends State<FirstRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: RaisedButton(
        child: Text('Open route'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => SecondRoute()),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    // Never called
    print("Disposing first route");
    super.dispose();
  }
}

class SecondRoute extends StatefulWidget {
  @override
  _SecondRouteState createState() => _SecondRouteState();
}

class _SecondRouteState extends State<SecondRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: RaisedButton(
        onPressed: () {
          Navigator.pop(context);
        },
        child: Text('Go back!'),
      ),
    );
  }

  @override
  void dispose() {
    print("Disposing second route");
    super.dispose();
  }
}

2 个答案:

答案 0 :(得分:6)

我知道有些晚了,但是我认为您应该重写deactivate方法。由于我们正在更改页面,因此实际上并没有在破坏它,这就是为什么未调用dispose的原因。

如果您想了解更多信息,this page lists有状态窗口小部件的生命周期。

通过链接:

'deactivate()'在从树中删除State时被调用,但它可能是 在当前帧更改完成之前重新插入。这种方法基本存在 因为状态对象可以从树中的一个点移动到另一点。

答案 1 :(得分:0)

在第一屏和第二屏之间路由时,请呼叫Navigator.pushReplacement

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatefulWidget {
  @override
  _FirstRouteState createState() => _FirstRouteState();
}

class _FirstRouteState extends State<FirstRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: RaisedButton(
        child: Text('Open route'),
        onPressed: () {
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(builder: (context) => SecondRoute()),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    // Never called
    print("Disposing first route");
    super.dispose();
  }
}

class SecondRoute extends StatefulWidget {
  @override
  _SecondRouteState createState() => _SecondRouteState();
}

class _SecondRouteState extends State<SecondRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: RaisedButton(
        onPressed: () {
          Navigator.pushReplacement(
            context,
            MaterialPageRoute(builder: (context) => FirstRoute()),
          );
        },
        child: Text('Go back!'),
      ),
    );
  }

  @override
  void dispose() {
    print("Disposing second route");
    super.dispose();
  }
}

尝试一下