You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:04:55