I want my Transaction screen to be categorized in months and i build the transaction screen using list view separated .
Here is my Transaction Screen code and i used the intl date package to get the date
class ScreenTransaction extends StatelessWidget {
  const ScreenTransaction({super.key});
  @override
  Widget build(BuildContext context) {
    TransactionDB.interface.refreshTransaction();
    CategoryDB.instance.refreshUI();
    return ValueListenableBuilder(
      valueListenable: TransactionDB.interface.transactionListNotifier,
      builder: (BuildContext ctx, List<TransactionModel> newList, _) {
        return ListView.separated(
          padding: EdgeInsets.all(10),
          itemBuilder: (ctx, index) {
            final _list = newList[index];
            return Slidable(
              key: Key(_list.id!),
              startActionPane: ActionPane(
                motion: DrawerMotion(),
                children: [
                  SlidableAction(
                    onPressed: (ctx) {
                      TransactionDB.interface.deleteTransaction(_list.id!);
                    },
                    icon: Icons.delete,
                    backgroundColor: Colors.red,
                    label: 'Delete',
                  ),
                ],
              ),
              child: Card(
                child: ListTile(
                  leading: CircleAvatar(
                    backgroundColor: _list.type == CategoryType.income
                        ? Colors.green
                        : Colors.red,
                    child: Text(
                      parsedDate(_list.date),
                      textAlign: TextAlign.center,
                    ),
                    radius: 30,
                  ),
                  title: Text('Rs ${_list.amount}'),
                  subtitle: Text(_list.categoryModel.name),
                ),
              ),
            );
          },
          separatorBuilder: (ctx, index) {
            return SizedBox(height: 10);
          },
          itemCount: newList.length,
        );
      },
    );
  }
  String parsedDate(DateTime date) {
    final _date = DateFormat.MMMd().format(date);
    final _splittedDate = _date.split(' ');
    return '${_splittedDate.last}\n ${_splittedDate.first}';
  }
}
This is how my transaction screen looks like now
I want a header like march 2024 and february 2024 and the the list items to be under that header.
 
                        
Here's a step by step guide on how I would do it.
1. Extract all the dates from your transaction list
newListto a new listdatesListI am using the
parsedDateHeadersfunction to exclude thedayfrom the date and create the header's format.2. Now that we have the list of dates by month, remove all the repeated/duplicated dates.
3. In your
ListViewwidget, use thedatesList(headers) as the itemCount.4. Now we can use a
Columnwidget to add headers and the transactions underneath it. But instead of adding anotherbuilderfor the transactions, usemappinginstead.5. Before mapping the transactions, use a function to compare the transaction's months with the header's month, then add them to a new list
_filteredListYou can also get the index of each transaction like this:
6. Now add the condition that if
_filteredListis empty (not the correct month), return SizedBox.shrink(), otherwise, return the transactions widget.See full demo here: https://dartpad.dev/?id=38334d9b986e39fa64cbdccb99636871