skip to Main Content

I want when I click on one of the Expansion Tiles, the rest of the items are closed, how can I do that?

Refer to below example code :

 import 'package:flutter/material.dart';

class PickPlanPage extends StatefulWidget {
  const PickPlanPage({Key? key}) : super(key: key);

  @override
  State<PickPlanPage> createState() => _PickPlanPageState();
}

class _PickPlanPageState extends State<PickPlanPage> {

  bool initiallyExpanded = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ListView.separated(
        itemCount: 5,
        separatorBuilder: (context, index) => const SizedBox(height: 20),
        itemBuilder: (context, index) => ExpansionTile(
          initiallyExpanded: false,
          title: const Text('title'),
          onExpansionChanged: (value) => setState(() => initiallyExpanded = value),
          children: const [
            Text('Description'),
          ],
        ),
      ),
    );
  }
}

2

Answers


  1. You can use ExpansionPanelList and track the selected item tap event.

    class PickPlanPage extends StatefulWidget {
      const PickPlanPage({Key? key}) : super(key: key);
    
      @override
      State<PickPlanPage> createState() => _PickPlanPageState();
    }
    
    class _PickPlanPageState extends State<PickPlanPage> {
      int? openIndex;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: Column(
            children: [
              ExpansionPanelList(
                children: [
                  for (int index = 0; index < 5; index++)
                    ExpansionPanel(
                      headerBuilder: (context, isExpanded) => GestureDetector(
                        onTap: () {
                          openIndex = index;
                          setState(() {});
                        },
                        child: const Text('title'),
                      ),
                      isExpanded: index == openIndex,
                      body: Column(
                        children: [
                          Text('Description'),
                        ],
                      ),
                    ),
                ],
              ),
            ],
          ),
        );
      }
    }
    
    
    Login or Signup to reply.
  2. You can archive in your existing code with small modification.

    make sure you need to add key in ListView & ExpansionTile widget. try bellow code.

    class _PickPlanPageState extends State<PickPlanPage> {
      int expandIndex = -1; // to handle only one expansion at a time. 
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: ListView.separated(
            key: Key(expandIndex.toString()), //<-- must add
            itemCount: 5,
            separatorBuilder: (context, index) => const SizedBox(height: 20),
            itemBuilder: (context, index) => ExpansionTile(
              key: Key(index.toString()), //<-- must add
              initiallyExpanded: (index == expandIndex), //<-- must add
              title: const Text('title'),
              onExpansionChanged: (value) {
                setState(() {
                  expandIndex = value ? index : -1;
                });
              },
              children: const [
                Text('Description'),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search