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

Flutter问题:如何从生成的List Tile跳转到新页面?

问题解决思路与代码修改

核心问题原因

子组件中嵌套了MaterialApp,这会创建一个独立的导航上下文(Navigator),导致路由跳转仅在该嵌套的MaterialApp内部生效,父组件的导航栈完全不受影响。同时原代码未给每个ListTile分配独立的目标路由。


分步解决方案

1. 移除子组件中的嵌套MaterialApp

子组件不需要单独创建MaterialApp,直接使用父组件提供的导航上下文即可。修改后的MyApp组件代码:

class MyApp extends StatelessWidget {
  final List<ListItem> items;
  final bool active;
  final ValueChanged<bool> onChanged;

  const MyApp({
    super.key,
    this.active = false,
    required this.onChanged,
    required this.items,
  });

  @override
  Widget build(BuildContext context) {
    const title = 'Agenda';

    // 移除MaterialApp,直接返回Scaffold复用父导航上下文
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.green[900],
        title: const Text(title),
      ),
      body: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) {
          final item = items[index];

          return ListTile(
            title: item.buildTitle(context),
            trailing: const Icon(Icons.check_circle_outline_sharp),
            subtitle: item.buildSubtitle(context),
            // 跳转逻辑改为读取当前Item绑定的目标页面
            onTap: () => Navigator.of(context).push(
              MaterialPageRoute(builder: (context) => item.targetPage),
            ),
          );
        },
      ),
    );
  }
}

2. 扩展ListItem类,添加路由绑定属性

让每个列表项携带自己的目标页面信息,修改ListItem抽象类和MessageItem实现:

/// 基础列表项抽象类,新增目标页面属性
abstract class ListItem {
  Widget buildTitle(BuildContext context);
  Widget buildSubtitle(BuildContext context);
  Widget get targetPage; // 绑定每个Item对应的跳转页面
}

/// 消息列表项实现,接收目标页面参数
class MessageItem implements ListItem {
  final String sender;
  final String body;
  @override
  final Widget targetPage;

  MessageItem(this.sender, this.body, {required this.targetPage});

  @override
  Widget buildTitle(BuildContext context) => Text(sender);

  @override
  Widget buildSubtitle(BuildContext context) => Text(body);
}

3. 父组件传递带路由信息的列表项

给每个生成的MessageItem分配对应的目标页面,可根据索引区分不同路由:

Container(
  height: 400,
  width: 300,
  child: MyApp(
    active: _active,
    onChanged: _handleTapboxChanged,
    items: List<ListItem>.generate(
      FILLME.length,
      (i) => FILLME[i] != null
          ? MessageItem(
              '${FILLME[i]}',
              'Exercise',
              // 这里可根据i传入不同页面,比如HiFlutterApp(index: i)
              targetPage: HiFlutterApp(),
            )
          : MessageItem(
              'Sender $i',
              'Exercise',
              // 也可以绑定其他自定义页面
              targetPage: HiFlutterApp(),
            ),
    ),
  ),
)

额外说明

  • 确保你的应用根组件是MaterialApp(通常在main.dart中),否则导航功能会失效。
  • 原代码中的_active和_handleTapboxChanged与路由问题无关,若无需控制组件可见性可考虑移除,保留则不影响修复效果。

内容的提问来源于stack exchange,提问作者Literalomicus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 04:20:34