flutter 如何在列表的每个项目中切换打开和关闭子菜单

ktca8awb  于 2023-03-09  发布在  Flutter
关注(0)|答案(1)|浏览(178)

我有一个项目列表。每个项目都有一个按钮来显示一个子菜单来执行一些操作。我想只显示一个子菜单并隐藏其他子菜单。当我点击IconButton时,它会显示和隐藏一个子菜单,并且工作正常,但当另一个项目子菜单打开时,我点击另一个,我无法处理隐藏另一个打开的子菜单和打开新点击的子菜单。
下面是截图:

下面是列表生成器

class List extends StatelessWidget {
  const List({super.key, this.items});
  final List<ListItem> items;

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return ItemListTile(
          miner: items[index],
        );
      },
      itemCount: items.length,
    );
  }
}

下面是ItemListTile代码:

class ItemListTile extends StatelessWidget {
  const ItemListTile({super.key, this.item});
  final Item item;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('title'),
      trailing: IconButton(
        onPressed: () {
          // How to toggle menus open and close state?
          if (isOpen) {
            closeMenu();
          } else {
            openMenu();
          }
        },
        icon: const Icon(
          Icons.more_vert_outlined,
          color: Colors.white,
        ),
        color: Colors.white,
      ),
    );
  }

  void openMenu() {
    // How to handle state?
    findButton();
    overlayEntry = _overlayEntryBuilder();
    Overlay.of(context, debugRequiredFor: widget).insert(overlayEntry!);
  }

  void closeMenu() {
    // How to handle state?
    overlayEntry?.remove();
  }

  @override
  void dispose() {
    overlayEntry?.remove();
    overlayEntry = null;
    super.dispose();
  }
}

我想学习使用有状态的小部件或块模式解决这个问题。提前感谢。

bvk5enib

bvk5enib1#

很抱歉使用setstate,因为我不知道您使用的是哪种状态管理,但我可以向您展示一个简单的示例,说明如何在一个状态打开时关闭其他状态:

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';

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

@override
State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
late int activeItem;
@override
void initState() {
activeItem =-1;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
  body: ListView.builder(
    itemCount: 5,
    itemBuilder: ((context, index) {
    return ListTile(
      title: Text("$index-title"),
      trailing: IconButton(onPressed: (){
        if(activeItem==index){
          closeMenu();
          activeItem=-1;
          setState(() {});

          }else{
            openMenu();
            activeItem =index;
            setState(() {});
          }
      }, icon: Icon(activeItem==index?Icons.more_vert:Icons.more_horiz)),
      subtitle: Text(activeItem==index?"Opened Subtitle":"closed 
Subtitle"),
    );
  })),
);
}
closeMenu(){
//Some logic here
}
openMenu(){
//Some logic here
}
}

相关问题