5

I have built a Listview with ExpansionTile. But Now I want that if I tap on an ExpansionTile then only that ExpansionTile should open and other Expanded ExpansionTile should close.

Please help me how can I achieve this?

Here is my Code for ExpansionTile

   @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: Text("Short Product"),
            ),
            body: ListView.builder(
              itemCount: Category_List.length,
              itemBuilder: (context, i) {
                return ExpansionTile(
                  title: Text(Category_List[i].cat_name),
                  children:_Product_ExpandAble_List_Builder(Category_List[i].cat_id)
                );
              },
            )
         );
      }

      _Product_ExpandAble_List_Builder(int cat_id) {
        List<Widget> columnContent = [];
        Product_List.forEach((product) => {
                columnContent.add(
                  ListTile(
                    title: ExpansionTile(
                        title: Text(product.prod_name),
                        ),
                    trailing: Text("${product.total_Qty} (Kg)"),
                  ),
                ),
            });
        return columnContent;
      }
}

Thanks in advance.

Habib ur Rehman
  • 438
  • 3
  • 12
  • 1
    Just a little advice.. All variable should be formatted in camel case starting with lower case letter. I'm not sure if formatting variable names otherwise will have any affect on functionality of the app but most importantly it is the rule to format it that way – LonelyWolf May 14 '20 at 08:04
  • 1
    Just use a `ExpansionPanelList.radio` - it does what you want. – Pierre Dec 30 '21 at 12:19
  • You can have a controller for each expansion tile and then using the controller you can manage the collapse and expand state. – Deepak Goyal May 25 '23 at 04:35

1 Answers1

8

you can programmatically change expansion tile should open or close.

I made similar to your code.

int selected; //attention

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Short Product"),
      ),
      body: ListView.builder(
        key: Key('builder ${selected.toString()}'), //attention
        itemCount: 10,
        itemBuilder: (context, i) {
          return ExpansionTile(
              key: Key(i.toString()), //attention
              initiallyExpanded: i == selected, //attention
              title: Text(i.toString()),
              children: _Product_ExpandAble_List_Builder(i),
              onExpansionChanged: ((newState) {
                if (newState)
                  setState(() {
                    selected = i;
                  });
                else
                  setState(() {
                    selected = -1;
                  });
              }));
        },
      ),
    );
  }

  _Product_ExpandAble_List_Builder(int cat_id) {
    List<Widget> columnContent = [];
    [1, 2, 4, 5].forEach((product) => {
          columnContent.add(
            ListTile(
              title: ExpansionTile(
                title: Text(product.toString()),
              ),
              trailing: Text("$product (Kg)"),
            ),
          ),
        });
    return columnContent;
  }
Viren V Varasadiya
  • 25,492
  • 9
  • 45
  • 61
  • 3
    Nice workaround almost same as this one https://stackoverflow.com/questions/59820265/i-want-first-expansiontiles-item-default-is-open-i-want-to-when-i-click-anothe/59896985#59896985 I think the right answer should be no it is not possible unless you create your own expansion tile. The build in expansion tiles aren't design to do this. Using this workarounds will damage all animations so it is quite useless unless you don't mind design. I'm waiting for this feature long time to be implemented into flutter expansion tile – LonelyWolf May 14 '20 at 07:52
  • Now i have a sublist how i can do this for that list?? – Habib ur Rehman May 14 '20 at 09:28
  • setState changes scroll position, Is there any way to get rid of it? – Harsh Pipaliya Feb 03 '21 at 14:09