how to close ExpansionTileCard when clicking on another card

442 Views Asked by At

I have a ListView with ExpansionTileCard. Everything is displayed normally, but there is a problem, when I click on the ExpansionTileCard widget, additional information opens, and when I click on another card, the previous one does not close. I want to call up some card so that only it is open. Here is my code:

  Widget _buildList(OrdersEntity ordersEntity) {
    return ListView.separated(
      itemCount: ordersEntity.length,
      itemBuilder: (BuildContext context, int position) {
        return _withButton(ordersEntity, position);
      },
      separatorBuilder: (BuildContext context, int index) {
        return const Divider(
          height: 0,
        );
      },
    );
  }

  Widget _withButton(OrdersEntity ordersEntity, int position) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        _getRow(
            name: ordersEntity.itemAtPositionName(position),
            date: ordersEntity.itemAtPositionDate(position),
            status: ordersEntity.itemAtPositionStatus(position),
            id: ordersEntity.idAtPosition(position),
            cost: ordersEntity.itemAtPositionCost(position),
            warranty: ordersEntity.itemAtPositionWarranty(position),
            master: ordersEntity.itemAtPositionMasterName(position),
            bonus: '122',
            onTap: (regionId) {
            }),
      ],
    );
  }

  Widget _getRow({
    required String name,
    required String date,
    required String status,
    required String cost,
    required String warranty,
    required String master,
    required String bonus,
    required String id,
    required ValueChanged<String> onTap,
  }) {
    return Material(
      color: Colorz.white,
      child: InkWell(

        splashColor: Colorz.selectedListItemBG2,
        child: BlocBuilder<OrderHistoryBloc, OrderHistoryState>(
            buildWhen: (previous, current) =>
            current is OrdersRemoveItemState,
            builder: (context, state) {
              bool progress;
              if (state is OrdersRemoveItemState && id == state.nameId) {
                progress = state.isProgress;
              } else {
                progress = false;
              }
              return Stack(
                children: [
                  progress
                      ? Center(
                    child: Container(
                        color: Colorz.transparent30,
                        child: const PlatformProgressIndicator()),
                  )
                      : const EmptyWidget(),
                  _listItemColumn(
                      name: name,
                      date: date,
                      status: status,
                      cost: cost,
                      warranty: warranty,
                      bonus: bonus,
                      master: master,
                      id: id
                  )
                ],
              );
            }),
        onTap: () {},
      ),
    );
  }

  _listItemColumn({
    required String name,
    required String date,
    required String status,
    required String master,
    required String bonus,
    required String cost,
    required String warranty,
    required String id,
  }) {

    return Column(children: [
      Padding(
          padding: EdgeInsets.all(10),
          child: Container(
            padding: EdgeInsets.only(top: 5), //control green
            decoration: BoxDecoration(
              color: _colorStatus(status),
              borderRadius: const BorderRadius.only(
                topLeft: Radius.circular(24),
                topRight: Radius.circular(24),
              ),
            ),
            child: Container(
              decoration: const BoxDecoration(
                color: Colors.white,
                borderRadius:BorderRadius.only(
                  topLeft: Radius.circular(24),
                  topRight: Radius.circular(24),
                ),
              ),

              child: ExpansionTileCard(
               initiallyExpanded: false,
                title: Text(name),
                subtitle: Text(date),
                trailing: Wrap(
                  spacing: 12, // space between two icons
                  children: <Widget>[
                    Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Material(
                          color: Colorz.transparents,
                          child: InkWrapper(
                            splashColor: Colorz.lighterGray,
                            child: IconButton(
                                alignment: Alignment.center,
                                icon: SvgPicture.asset(
                                  Img.listItemMenu,
                                ),
                                onPressed: null
                            ),
                            onTap: () {
                            },
                          ),
                        ),
                        Text(
                          status,
                          textAlign: TextAlign.left,
                          maxLines: 1,
                          style: TextStyle(
                            color: _colorStatus(status),
                            overflow: TextOverflow.ellipsis,
                            fontSize: FontSize.tiny,
                          ),
                        ),
                      ],
                    )
                  ],
                ),
                children: [
                  _buildTextLine(
                    Titles.orderMaster,
                    null,
                    master,
                  ),
                  Container(
                    height: Margins.tiny,
                  )

                ],
              ),
            ),
          )
      ),
    ]
    );

  }
}

1

There are 1 best solutions below

7
On

I think it would be better to use ExpansionPanelList in this case. A int to hold the state.

 int? _selectedIndex;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          expansionCallback: (i, b) {
          if (_selectedIndex == i)
            _selectedIndex = null;
          else
            _selectedIndex = i;
          setState(() {});
          },
          children: List.generate(
            23,
            (index) => ExpansionPanel(
              canTapOnHeader: true,
              isExpanded: index == _selectedIndex,
              headerBuilder: (context, isExpanded) {
                return Text("header $index");
              },
              body: Column(
                children: [
                  Text("body $index"),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }