当Navigator.push不在作用域内时,如何调用setState?

移动开发 2026-07-10

我有一个MainScreen,它有一个自定义的AppBar。这个AppBar包含前往SettingsScreen的按钮。我想实现如下行为:用户通过常用的返回按钮/手势离开SettingsScreen后,会返回到根据设置中所选选项刷新过的MainScreen。

我已经看到这样一种在返回时设置状态的解决方案:

Navigator.push( context, MaterialPageRoute( builder: (context) => Settingsscreen()), ).then((value){setState((){});});

然而,这个并不在mainScreen类中,因此会返回一个“方法未定义”的错误。

这是相关的代码:

MainScreen

class MainScreen extends StatefulWidget{
  const MainScreen({super.key});

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen>{
  final MainViewModel mainVM = MainViewModel();
  late List<Plant> plants;


  @override
  void initState(){
    mainVM.fetchPlants();
    super.initState();
  }

  @override
  void dispose(){
    mainVM.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context){

    return Scaffold(
      appBar: PlantAppBar(true),
      backgroundColor: Theme.of(context).colorScheme.surface,

      body: 
      StreamBuilder<List<Plant>>(
          stream: mainVM.plantStream,
          builder: (context, snapshot) {
            if (snapshot.hasError){
              return Text("Error: ${snapshot.error}", style: TextStyle(color: Colors.red));
            }else if (snapshot.hasData){
              plants = snapshot.data!;
              return _buildListView();
            }else{
              return Center(child: Text("Nutze den (+) Button um deine erste Pflanze anzulegen"));
            }


          }),
);}
}

这段来自自定义AppBar的代码

class PlantAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  final Size preferredSize = Size.fromHeight(50);
  final String title = 'Pflanzen';
  final bool showSettingsButton;

  PlantAppBar(this.showSettingsButton, {super.key});

  @override
  Widget build(BuildContext context) {
    return AppBar(
      actions: [?settingsButton(showSettingsButton, context)],
      automaticallyImplyLeading: false,
      title: Text(title, style: TextStyle(color: Theme.of(context).colorScheme.onPrimary),
      ),
      backgroundColor: Theme.of(context).colorScheme.primary,
      toolbarTextStyle: TextStyle(color: Theme.of(context).colorScheme.onPrimary),
    );
  }

  Widget? settingsButton(bool show, context){
    if (show == false) return null;
    return IconButton(onPressed: (){navigateToSettings(context);}, icon: Icon(Icons.more_vert, color: Theme.of(context).colorScheme.onPrimary,));
  }

  void navigateToSettings(context){
    Navigator.push( context, MaterialPageRoute( builder: (context) => Settingsscreen()), ); // .then((value){setState((){});}); // <= doesn't compile
  }

}

解决方案

如果你需要在一个小部件的改动触发另一个小部件的重新构建,你需要一种对共享资源具有可观察数据的状态管理方案。简单地说,如果你曾经说过“我想在[某个其他小部件]中触发setState”,你就需要状态管理。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章