Flutter Drawer with nested ListView.builder not scrolling

26 Views Asked by At

I'm working on a Flutter application and I have a Drawer that contains a main ListView with multiple children. Within each child, there's a Column widget that contains a ListView.builder. I've implemented a Drawer with nested ListView.builder widgets, but I'm facing an issue where I can't scroll through the list items.

Here's the SideMenu widget code:

    import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:widgetbook_tlf/src/core/constants/app_colors.dart';
import '../core/constants/app_text_styles.dart';
import '../models/side_menu_models/side_menu_section_model.dart';

class SideMenu extends StatefulWidget {
  const SideMenu({super.key, required this.sections, required this.menuLogo});
  final List<Sections> sections;
  final Widget menuLogo;

  @override
  State<SideMenu> createState() => _SideMenuState();
}


class _SideMenuState extends State<SideMenu> {
  int selectedItemIndex = -1;
  final ScrollController _scrollController = ScrollController();


@override
  Widget build(BuildContext context) {

    return  Drawer(

      backgroundColor: AppColors.backgroundLightYellow.color,
      child: ListView(
        controller: _scrollController,
        physics: AlwaysScrollableScrollPhysics(),
       // scrollDirection: Axis.vertical,
      //  shrinkWrap: true,
        children: [

          Align(
              alignment: Alignment.centerLeft,
              child: Padding(
              padding: EdgeInsets.all(16.0),
                child: widget.menuLogo,
    ),
          ),

          for (int sectionIndex = 0;
          sectionIndex < widget.sections.length;
          sectionIndex++)

            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Column(

                crossAxisAlignment: CrossAxisAlignment.start,
                children: [

                  Text(
                    widget.sections[sectionIndex].sectionName,
                    style: AppTextStyles.sideMenuSectionText400,),
                  ListView.builder(
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemCount: widget.sections[sectionIndex].items.length,
                      itemBuilder: (BuildContext context, int index){
                        final item =
                        widget.sections[sectionIndex].items[index];
                        final isSelected =
                            selectedItemIndex == (sectionIndex * 1000) + index;
                        return Container(
                          padding: EdgeInsets.symmetric(horizontal: 15,vertical: 8),

                          decoration: BoxDecoration(

                              border: Border.all(
                                style: BorderStyle.none,
                              ),
                             color: isSelected ? AppColors.purpleLight.color : Colors.transparent ,
                            borderRadius: BorderRadius.circular(100)
                          ),
                          child: ListTile(

                            contentPadding: const EdgeInsets.symmetric(horizontal: 0),

                            hoverColor: Colors.transparent,
                            title: Text(item.itemName,
                                style: AppTextStyles.sideMenuSectionItem700(isSelected: isSelected)
                            ),
                            leading: Container(
                              width: 24,
                              height: 24,
                              child: SvgPicture.string(
                                item.leadingIcon,
                                color: isSelected ? AppColors.purple.color : AppColors.black.color,
                              ) ,
                            ),
                            trailing:  Container(
                              width: 24,
                              height: 24,
                              child: item.trailingIcon,
                            ),
                            onTap: (){
                              setState(() {
                                selectedItemIndex =
                                    (sectionIndex * 1000) + index;
                              });
                              item.onTap();

                            },
                          ),
                        );
                  }
                  ),



                  const Padding(
                      padding: EdgeInsets.symmetric(horizontal: 16,vertical: 10),
                      child: Divider(height: 1)
                  )
                ],
              ),
            )

        ],

      ),
    );
   }
 }

The Drawer contains several sections, each with its own ListView.builder to create a list of items. I've set shrinkWrap to true and physics to NeverScrollableScrollPhysics() for the nested ListView.builders, as I want them to be fully expanded and only the outer ListView to be scrollable.

I'm using a ScrollController for the main ListView, but the content still doesn't scroll. The behavior I'm expecting is that the entire drawer should scroll when the content exceeds the screen height.

Here's what I've tried so far:

Ensured AlwaysScrollableScrollPhysics is set on the main ListView. Wrapped the nested ListView.builder with Expanded to force it to take any available space. Verified that the Drawer is not nested within another scrollable widget. However, none of these solutions have worked. I'm not sure if it's an issue with the way I've structured the widgets or if there's something else I'm missing.

My questions are:

Why isn't the Drawer content scrolling when using a nested ListView.builder? How can I make the entire Drawer content scrollable while keeping the structure of having multiple sections with lists? Any insights or solutions would be greatly appreciated!

0

There are 0 best solutions below