Flutter技术求助:如何将WillPopScope替换为PopScope并修改代码?
将WillPopScope替换为PopScope的修改方案
Flutter 3.12及以上版本中,WillPopScope已被PopScope组件取代,以下是适配你现有代码的修改实现:
修改后的完整代码
import 'package:flutter/material.dart'; import '../models/data_layer.dart'; import '../plan_provider.dart'; class PlanScreen extends StatefulWidget { final Plan plan; const PlanScreen({ super.key, required widget.plan, }); @override State<PlanScreen> createState() => _PlanScreenState(); } class _PlanScreenState extends State<PlanScreen> { late ScrollController scrollController; Plan get plan => widget.plan; @override void initState() { scrollController = ScrollController() ..addListener(() { FocusScope.of(context).requestFocus(FocusNode()); }); super.initState(); } @override Widget build(BuildContext context) { // 替换WillPopScope为PopScope return PopScope( // 拦截返回动作的回调 onPopInvoked: (bool didPop) async { if (!didPop) { // 执行保存逻辑 final controller = PlanProvider.of(context); controller.savePlan(plan); // 手动触发返回 if (mounted) { Navigator.of(context).pop(); } } }, child: Scaffold( appBar: AppBar(title: const Text('Master Plan')), body: Column(children: [ Expanded(child: _buildList()), SafeArea(child: Text(plan.completenessMessage)) ]), floatingActionButton: _buildAddTaskButton(), ), ); } Widget _buildAddTaskButton() { return FloatingActionButton( child: const Icon(Icons.add), onPressed: () { final controller = PlanProvider.of(context); controller.createNewTask(plan); setState(() {}); }, ); } Widget _buildList() { return ListView.builder( controller: scrollController, itemCount: plan.tasks.length, itemBuilder: (context, index) => _buildTaskTile(plan.tasks[index]), ); } Widget _buildTaskTile(Task task) { return Dismissible( key: ValueKey(task), background: Container(color: Colors.red), direction: DismissDirection.endToStart, onDismissed: (_) { final controller = PlanProvider.of(context); controller.deleteTask(plan, task); setState(() {}); }, child: ListTile( leading: Checkbox( value: task.complete, onChanged: (selected) { setState(() { task.complete = selected ?? false; }); }), title: TextFormField( initialValue: task.description, onFieldSubmitted: (text) { setState(() { task.description = text; }); }, )), ); } @override void dispose() { scrollController.dispose(); super.dispose(); } }
关键修改点说明
- 组件替换:直接将外层的
WillPopScope替换为PopScope - 回调逻辑调整:
- 使用
onPopInvoked替代onWillPop,参数didPop用于判断返回动作是否已完成 - 当
didPop为false时,说明返回动作尚未执行,此时先执行保存计划的逻辑,再手动调用Navigator.of(context).pop()完成返回
- 使用
- 状态判断:添加
mounted检查,避免在组件已销毁时执行导航操作,防止报错
内容的提问来源于stack exchange,提问作者user3523406
相关产品推荐
相关产品推荐

