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

Flutter:PopupMenuButton打开时触发事件设置ListView选中索引

解决PopupMenuButton打开时选中对应列表项的问题

要实现打开列表项右侧的PopupMenuButton时,立刻将selectedIndex设为对应行的序号,只需要用到PopupMenuButton的onOpened回调——这个回调会在弹出菜单刚打开的瞬间触发,完全符合需求。

修改步骤:

  • 在PopupMenuButton中添加onOpened参数,在回调里调用setState更新selectedIndex为当前行的索引i。

修改后的完整代码:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final GlobalKey<ScaffoldState> _scaffoldkey = new GlobalKey<ScaffoldState>();

  final List<String> _names = [
    'Liam', 'Noah', 'Oliver', 'William', 'Elijah',
  ];

  int selectedIndex = -1 ;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldkey,
      appBar: AppBar(
        title: Text('Pop Menu with List'),
      ),
      body: ListView.builder(
        itemBuilder: (_, i) {
          String name = _names[i];
          return ListTile(
              title: (selectedIndex == i)  ? Text('$name', style: TextStyle(fontWeight: FontWeight.bold),) : Text('$name'),
              onTap: () {
                setState(() {
                  selectedIndex =  i;
                });
            },
            trailing: PopupMenuButton(
              icon: Icon(Icons.more_vert),
              // 新增:打开菜单时选中当前行
              onOpened: () {
                setState(() {
                  selectedIndex = i;
                });
              },
              itemBuilder: (context) {
                return [
                  PopupMenuItem(
                    value: 'edit',
                    child: Text('Edit'),
                  ),
                  PopupMenuItem(
                    value: 'delete',
                    child: Text('Delete'),
                  )
                ];
              },
              onSelected: (String value) => actionPopUpItemSelected(value, name),
            ),
          );
        },
        itemCount: _names.length,
      ),
    );
  }

  void actionPopUpItemSelected(String value, String name) {
    ScaffoldMessenger.of(context).hideCurrentSnackBar;
    String message;
    if (value == 'edit') {
      message = 'You selected edit for $name';
    } else if (value == 'delete') {
      message = 'You selected delete for $name';
    } else {
      message = 'Not implemented';
    }
    final snackBar = SnackBar(content: Text(message));
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  }
}

说明:

  • onOpened是PopupMenuButton的内置回调,触发时机为菜单弹出的瞬间,早于onSelected(选中菜单项时触发)和onCanceled(菜单关闭但未选中项时触发)。
  • 通过在onOpened里调用setState更新selectedIndex,就能实现打开菜单时立刻高亮对应行的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:55:54