skip to Main Content

i am buildng a app which has categories, sub categories and sub-sub-categories, i want to do something like this in image

the third dropdown should be check boxes with multiple selections
what can i do. i am using listview builder for displaying primary list.

this is my code

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class LookingForScreen extends StatefulWidget {
  const LookingForScreen({super.key});

  @override
  State<LookingForScreen> createState() => _LookingForScreenState();
}

class _LookingForScreenState extends State<LookingForScreen>
    with TickerProviderStateMixin {
  late final _controllerAddPriceBtn = AnimationController(
    duration: const Duration(milliseconds: 500),
    vsync: this,
  )..value = 1.0;
  late final Animation<double> _animationAddPriceBtn = CurvedAnimation(
    parent: _controllerAddPriceBtn,
    curve: Curves.fastOutSlowIn,
  );

  late final _controllerDetailsView = AnimationController(
    duration: const Duration(milliseconds: 500),
    vsync: this,
  );

  late final Animation<double> _animationDetailsView = CurvedAnimation(
    parent: _controllerDetailsView,
    curve: Curves.fastOutSlowIn,
  );
  @override
  void dispose() {
    _controllerAddPriceBtn.dispose();
    _controllerDetailsView.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    var mQSize = MediaQuery.of(context).size;
    var mQWidth = mQSize.width;
    var mQHeight = mQSize.height;
    return Scaffold(
      bottomNavigationBar: Container(
        color: Colors.red,
        height: 70,
        width: double.infinity,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            TextButton(
                onPressed: () {},
                child: Text(
                  '0 Service Added',
                  style: TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                  ),
                )),
            Text(
              "|",
              style: TextStyle(
                fontWeight: FontWeight.bold,
                color: Colors.white,
              ),
            ),
            Row(
              children: [
                TextButton(
                    onPressed: () {},
                    child: Text(
                      'Get Budget',
                      style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    )),
                IconButton(
                    onPressed: () {},
                    icon: Icon(
                      Icons.arrow_forward,
                      color: Colors.white,
                    ))
              ],
            )
          ],
        ),
      ),
      backgroundColor: Colors.white,
      body: SingleChildScrollView(
        child: Container(
          margin: EdgeInsets.symmetric(horizontal: 15),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              SizedBox(height: mQHeight / 15),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Row(
                    children: [
                      IconButton(
                        icon: Icon(Icons.arrow_back_ios),
                        onPressed: () {
                          Get.back();
                        },
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      IconButton(
                        onPressed: () {
                          Get.to(NotificationsScreen());
                        },
                        icon: Badge(
                          backgroundColor: Colors.red,
                          isLabelVisible: true,
                          label: const Text("2"),
                          child: const Icon(Icons.notifications_none_outlined),
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          // do something
                          Get.snackbar('Clicked on ', 'Favorite');
                        },
                        icon: Badge(
                          backgroundColor: Colors.red,
                          isLabelVisible: true,
                          label: const Text("3"),
                          child: const Icon(Icons.favorite_outline),
                        ),
                      ),
                      IconButton(
                        onPressed: () {
                          Get.snackbar('Clicked on ', 'Profile');
                        },
                        icon: Image.asset(
                          'assets/images/profile.png',
                          width: mQWidth / 13,
                        ),
                      ),
                    ],
                  ),
                ],
              ),
              SizedBox(height: 10),
              Text(
                'Looking for',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontFamily: 'Poppins',
                  fontSize: 22,
                ),
              ),
              SizedBox(
                height: 1000,
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: 12,
                  itemBuilder: (context, index) {
                    return Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Row(
                              children: [
                                Image.asset(
                                  'assets/images/graphics.png',
                                  width: 80,
                                  height: 80,
                                ),
                                SizedBox(width: 10),
                                Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      'Graphics Design',
                                      style: TextStyle(
                                        fontSize: 20,
                                        fontWeight: FontWeight.bold,
                                      ),
                                    ),
                                    Text('Logo, flyer, poster, banner...')
                                  ],
                                ),
                              ],
                            ),
                            ScaleTransition(
                              alignment: Alignment.centerRight,
                              scale: _animationAddPriceBtn,
                              child: IconButton(
                                  onPressed: () {
                                    _controllerAddPriceBtn.reverse();
                                    _controllerDetailsView.forward();
                                  },
                                  icon: Icon(Icons.arrow_forward_ios)),
                            ),
                          ],
                        ),
                        SizeTransition(
                          sizeFactor: _animationDetailsView,
                          child: Container(
                              //
                              ),
                        ),
                        Divider(),
                      ],
                    );
                  },
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}

but i am unable to do . please help. enter image description here

2

Answers


  1. You can use the ExpansionTile widget to achieve the functionality.

    Example:

           ExpansionTile(
              title: const Text('ExpansionTile with explicit controller.'),
              children: <Widget>[
                Container(
                  alignment: Alignment.center,
                  padding: const EdgeInsets.all(24),
                  child: const Text('ExpansionTile Contents'),
                ),
              ],
            ),
    
    Login or Signup to reply.
  2. i have done this in an pet’s cearing app, here it is how i made it done

    first create Model for it

    class PetCareService {
      String name;
      bool isSelected;
    
      PetCareService({required this.name, this.isSelected = false});
    }
    

    and utlize this code

    class MultiSelectPetCareDropdown extends StatefulWidget {
      @override
      _MultiSelectPetCareDropdownState createState() => _MultiSelectPetCareDropdownState();
    }
    
    class _MultiSelectPetCareDropdownState extends State<MultiSelectPetCareDropdown> {
      List<PetCareService> _services = [
        PetCareService(name: 'Grooming'),
        PetCareService(name: 'Vet Check-up'),
        PetCareService(name: 'Training'),
        PetCareService(name: 'Walking'),
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Select Pet Care Services'),
          ),
          body: Center(
            child: DropdownButtonHideUnderline(
              child: DropdownButton(
                hint: Text('Select Services'),
                isExpanded: true,
                icon: Icon(Icons.arrow_drop_down),
                onChanged: (_) {},
                items: [
                  DropdownMenuItem(
                    child: MultiSelectItemWidget(
                      items: _services,
                      onChanged: (selectedItems) {
                        setState(() {
                          _services = selectedItems;
                        });
                      },
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    class MultiSelectItemWidget extends StatefulWidget {
      final List<PetCareService> items;
      final ValueChanged<List<PetCareService>> onChanged;
    
      MultiSelectItemWidget({required this.items, required this.onChanged});
    
      @override
      _MultiSelectItemWidgetState createState() => _MultiSelectItemWidgetState();
    }
    
    class _MultiSelectItemWidgetState extends State<MultiSelectItemWidget> {
      List<PetCareService> _selectedItems = [];
    
      @override
      void initState() {
        super.initState();
        _selectedItems = widget.items;
      }
    
      @override
      Widget build(BuildContext context) {
        return PopupMenuButton<int>(
          itemBuilder: (context) {
            return List.generate(widget.items.length, (index) {
              return PopupMenuItem(
                value: index,
                child: StatefulBuilder(
                  builder: (context, setState) {
                    return CheckboxListTile(
                      title: Text(widget.items[index].name),
                      value: widget.items[index].isSelected,
                      onChanged: (bool? value) {
                        setState(() {
                          widget.items[index].isSelected = value!;
                        });
                        widget.onChanged(widget.items);
                      },
                    );
                  },
                ),
              );
            });
          },
          child: Container(
            padding: EdgeInsets.all(15.0),
            decoration: BoxDecoration(
              border: Border.all(color: Colors.grey),
              borderRadius: BorderRadius.circular(5.0),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Text(
                  _selectedItems.where((item) => item.isSelected).map((item) => item.name).join(', '),
                  style: TextStyle(fontSize: 16),
                ),
                Icon(Icons.arrow_drop_down),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search