Ravindra S. Patil
Ravindra S. Patil

Reputation: 14785

Flutter Submenu in drawer with List

I want to put my Lists items in ExpansionTile, the title is set perfectly but children's items not set inside list. I want to add children items inside ExpansionTile children

My dataList:

List dataList = [
    {
      "title": "Payments",
      "icon": Icons.payment,
      "children": [
        {"title": "Paypal"},
        {"title": "Credit Card"},
        {"title": "Debit Card"}
      ]
    },
    {
      "title": "Favorite",
      "icon": Icons.favorite,
      "children": [
        {"title": "Swimming"},
        {"title": "Football"},
        {"title": "Movie"},
        {"title": "Singing"},
        {"title": "Jogging"},
      ]
    },
  ];
 

var declarion:

int? selected; 

My Widget:

    ListView.builder(
        key: Key('builder ${selected.toString()}'),
        padding: const EdgeInsets.only(left: 13.0, right: 13.0, bottom: 25.0),
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        itemCount: dataList.length,
        itemBuilder: (context, index) {
          return ExpansionTile(
            key: Key(index.toString()), 
            initiallyExpanded: index == selected, 
            trailing: const SizedBox(),
            leading: Icon(
              dataList[index]['icon'],
              color: index == selected ? Colors.black : Colors.grey,
            ),
            title: Text(dataList[index]['title'],
                style: TextStyle(
                    color: index == selected ? Colors.black : Colors.grey,
                    fontSize: 17.0,
                    fontWeight: FontWeight.bold)),
            onExpansionChanged: ((newState) {
              if (newState) {
                setState(() {
                  selected = index;
                });
              } else {
                setState(() {
                  selected = -1;
                });
              }
            }),
            children: [
              Padding(
                padding: const EdgeInsets.all(25.0),
                child: Text(
                  dataList[index]['children'][index]['title'],
                  style: TextStyle(
                    color: index == selected ? Colors.red : Colors.grey,
                  ),
                ),
              ),
            ],
          );
        },
      )

Current Result-

image

image

Upvotes: 0

Views: 481

Answers (2)

eamirho3ein
eamirho3ein

Reputation: 17900

You can define new variable like this:

int childSelected = -1;

then change your children to this:

children: dataList[index]['children']
                .map<Widget>((Map<String, String> item) {
              int i = (dataList[index]['children'] as List).indexOf(item);
              return InkWell(
                onTap: () {
                  setState(() {
                    childSelected = i;
                  });
                },
                child: Padding(
                  padding: const EdgeInsets.all(25.0),
                  child: Text(
                    item['title'].toString(),
                    style: TextStyle(
                      color: i == childSelected ? Colors.red : Colors.grey,
                    ),
                  ),
                ),
              );
            }).toList(),

and also reset it every time onExpansionChanged call:

onExpansionChanged: ((newState) {
          if (newState) {
            setState(() {
              childSelected = -1;
              selected = index;
            });
          } else {
            setState(() {
              selected = -1;
            });
          }
        }),

Upvotes: 2

OMi Shah
OMi Shah

Reputation: 6186

Because you're only showing the index position item and not actually mapping all the children of dataList[index]['children'].

Change:

 children: [
              Padding(
                padding: const EdgeInsets.all(25.0),
                child: Text(
                  dataList[index]['children'][index]['title'],
                  style: TextStyle(
                    color: index == selected ? Colors.red : Colors.grey,
                  ),
                ),
              ),
            ],

to:

children: dataList[index]['children']
                .map<Padding>((Map<String, String> item) => Padding(
                      padding: const EdgeInsets.all(25.0),
                      child: Text(
                        item['title'].toString(),
                        style: TextStyle(
                          color: index == selected ? Colors.red : Colors.grey,
                        ),
                      ),
                    ))
                .toList(),

Upvotes: 1

Related Questions