每次重新进入页面时都会调用 Flutter initState

问题描述 投票:0回答:1

我有三个页面,A、B、C,我通过抽屉在它们之间导航。

我的目标是让 initState 只被调用一次(当页面被插入 widget 树时),这样当我返回它时每个页面的状态都不会重新初始化。

我的第一个尝试是使用

Navigator.of(context).PushNamed(routeName)
,如下面的代码所示。 可能这不起作用,因为如果我从 A 调用 B 然后再调用 A,导航器堆栈是

[A] --> [B, A] --> [A, B, A] 而不是

[A] -> [B, A] --> [A]

所以基于pop()的导航应该更合适。我试过

onTap: () {
              Navigator.of(context).canPop()
                  ? Navigator.of(context)
                      .popUntil(ModalRoute.withName(PageA.routeName))
                  : Navigator.of(context).pushNamed(PageA.routeName);
            },

代替

onTap: () => Navigator.of(context).pushNamed(PageA.routeName)
但它不起作用:当我点击抽屉项目时,出现黑屏,没有任何异常或警告,就好像导航器调用了一个黑屏......

我做错了什么?知道如何解决吗?

这是我的代码:

main.dart

import 'package:flutter/material.dart';
import 'page_c.dart';
import 'page_a.dart';
import 'page_b.dart';
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Navigation test',
      home: PageA(),
      routes: {
        PageA.routeName: (ctx) => PageA(),
        PageB.routeName: (ctx) => PageB(),
        PageC.routeName: (ctx) => PageC(),
      },
    );
  }
}

my_drawer.dart

import 'package:flutter/material.dart';
import 'page_b.dart';
import 'page_c.dart';
import 'page_a.dart';

class MyDrawer extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: Column(
        children: [
          SizedBox(
            height: 100,
          ),
          ListTile(
              title: Text('PAGE A'),
              onTap: () => Navigator.of(context).pushNamed(PageA.routeName)),
          ListTile(
              title: Text('PAGE B'),
              onTap: () => Navigator.of(context).pushNamed(PageB.routeName)),
          ListTile(
              title: Text('PAGE C'),
              onTap: () => Navigator.of(context).pushNamed(PageC.routeName)),
        ],
      ),
    );
  }
}

page_a.dart

import 'package:flutter/material.dart';
import 'my_drawer.dart';

class PageA extends StatefulWidget {
  static const routeName = '/route-a';

  @override
  _PageAState createState() => _PageAState();
}

class _PageAState extends State<PageA> {
  @override
  void initState() {
    print('PAGE A INIT STATE');
    super.initState();
  }

  // void didChangeDependencies() {
  //   print('PAGE A DID CHANGE DEPENDECIES');
  //   super.didChangeDependencies();
  // }

  // @override
  // void dispose() {
  //   print('PAGE A DISPOSE');
  //   super.dispose();
  // }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PAGE A')),
      drawer: MyDrawer(),
      body: Center(
        child: Text('A', style: TextStyle(fontSize: 100)),
      ),
    );
  }
}

page_b.dart

import 'package:flutter/material.dart';
import 'my_drawer.dart';

class PageB extends StatefulWidget {
  static const routeName = '/route-b';

  @override
  _PageBState createState() => _PageBState();
}

class _PageBState extends State<PageB> {
  @override
  void initState() {
    print('PAGE B INIT STATE');
    super.initState();
  }

  // void didChangeDependencies() {
  //   print('PAGE B DID CHANGE DEPENDECIES');
  //   super.didChangeDependencies();
  // }

  // @override
  // void dispose() {
  //   print('PAGE B DISPOSE');
  //   super.dispose();
  // }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PAGE B')),
      drawer: MyDrawer(),
      body: Center(
        child: Text('B', style: TextStyle(fontSize: 100)),
      ),
    );
  }
}

page_c.dart

import 'package:flutter/material.dart';
import 'my_drawer.dart';

class PageC extends StatefulWidget {
  static const routeName = '/route-c';

  @override
  _PageCState createState() => _PageCState();
}

class _PageCState extends State<PageC> {
  @override
  void initState() {
    print('PAGE C INIT STATE');
    super.initState();
  }

  // void didChangeDependencies() {
  //   print('PAGE C DID CHANGE DEPENDECIES');
  //   super.didChangeDependencies();
  // }

  // @override
  // void dispose() {
  //   print('PAGE C DISPOSE');
  //   super.dispose();
  // }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('PAGE C')),
      drawer: MyDrawer(),
      body: Center(
        child: Text('C', style: TextStyle(fontSize: 100)),
      ),
    );
  }
}
flutter state navigation-drawer
1个回答
0
投票

Flutter stack working flow

根据图像,一个 flutter stack 正在工作。已经将屏幕添加到堆栈中。如果你添加 B,它只会被推到 A 之上。现在,B 和 A 在堆栈中。现在,A也处于直播状态。 B也处于直播状态。 B 将是您可见的状态屏幕。而在后台A也处于运行状态。 A不会被处置。

解决方案:

你应该使用

Navigator.popAndPushNamed(context, B.id);
,通过使用 popAndPushNamed 方法,你可以从堆栈中删除 A,B 将成为活动屏幕。

© www.soinside.com 2019 - 2024. All rights reserved.