How to make two tap events in ListTile?

278 views Asked by At

To begin with, i have the CustomExpansionPanelList widget as a parent. Then a list of children of the CustomExpansionPanel. In the headerBuilder is the ListTile, which has text and an icon on trailing. The problem: the onPressed event is hard to catch by the CustomExpansionPanel. A specific tap must be done.

Note: CustomExpansionPanelList and CustomExpansionPanel are classes modified by me. Removing the 'Custom' you get the classes of the widget itself.

The code:

CustomExpansionPanelList(
      elevation: 0,
      expandedHeaderPadding: EdgeInsets.zero,
      expansionCallback: (i, isOpen) {
       ///some code
      },
      children: [
        CustomExpansionPanel(
          canTapOnHeader: true,
          isExpanded: true,
          body: const SomeBody(),
          headerBuilder: (context, isOpen) {
            return ListTile(
                iconColor: Colors.white,
                contentPadding: const EdgeInsets.symmetric(
                    horizontal: 20.0),
                title: const Text(
                  'some text',
                ),
                trailing: Transform.translate(
                    offset: const Offset(30, 0),
                    child: Container(
                      margin: EdgeInsets.all(8),
                      child: IconButton(
                          icon: Icon(Icons.edit_outlined),
                          onPressed: () => someAction()
                              )),
                    )));
          },
        ),
])
2

There are 2 answers

0
Peter Henter On BEST ANSWER

You could just set canTapOnHeader: false in the CustomExpansionPanel widget. That way taps on your IconButton in the header are registered correctly, and you can expand/collapse the body of the CustomExpansionPanel by tapping on the little arrow icon to the right of your IconButton

  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<bool> panelIsExpanded = [true];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          elevation: 0,
          expandedHeaderPadding: EdgeInsets.zero,
          expansionCallback: (panelIndex, isExpanded) => setState(() {
            panelIsExpanded[panelIndex] = !panelIsExpanded[panelIndex];
          }),
          children: [
            ExpansionPanel(
              canTapOnHeader: false,
              isExpanded: panelIsExpanded[0],
              body: const Text('This is the body of the expansion panel'),
              headerBuilder: (context, isOpen) {
                return ListTile(
                  iconColor: Colors.black,
                  contentPadding: const EdgeInsets.symmetric(horizontal: 20.0),
                  title: const Text(
                    'some text',
                  ),
                  trailing: Transform.translate(
                    offset: const Offset(30, 0),
                    child: Container(
                      margin: const EdgeInsets.all(8),
                      child: IconButton(
                        icon: const Icon(Icons.edit_outlined),
                        onPressed: () =>
                            ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text(
                                'You tapped the edit icon on the header of the expansion panel'),
                          ),
                        ),
                      ),
                    ),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}
2
Md. Yeasin Sheikh On

ListTile provides onTap method, you can use it.

return ListTile(
  onTap: () {
    
  },
  iconColor: Colors.white,

More about ListTile