DEV Community

Ambareesha AV
Ambareesha AV

Posted on

Force dropdown menu items to open under the dropdown button in Flutter

Problem statement
By default dropdown menu items open on top of the dropdown button, and when we get a design showing dropdown menu items listed under the dropdown button, somehow the developer has to figure out how to achieve it.

How I achieved it
we will be using Flutter is one of the well-matured cross-platform app development frameworks out there and we can build pixel-perfect apps from it.
I will be using vscode as my code editor, let's create a flutter project,
open pubspec.yaml and add this package dropdown_button2

Image description
with this package, we can design dropdown button and menu UI however we want.
so in this article, we are focusing only on opening menu items under the dropdown button.

Let's open main.dart delete all unwanted code, add default DropdownButton() widget with items and also add DropdownButton2() into Column.
I'm using Faker package to generate menu items

dropdown buttons

magic happens in these lines of code

dropdownStyleData: DropdownStyleData(
                    maxHeight: MediaQuery.of(context).size.height * 0.3),
Enter fullscreen mode Exit fullscreen mode

here I'm giving 30% of the screen size because I placed dropdown buttons in the center of the screen so it will work here but if you want to place dropdown button in different place of the screen then you have to changes maxHeight value based on your UI

default dropdown widget
default dropdown widget
menu items under dropdown button
menu items under dropdown button

here is the full code.

import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:faker/faker.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Dropdown menu items',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Dropdown menu items'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> getNamesList(int length) {
    return List.generate(length, (index) => Faker().food.dish())
        .toSet()
        .toList();
  }

  List<DropdownMenuItem<String>> getItems(List<String> list) {
    return list.map((e) => DropdownMenuItem(value: e, child: Text(e))).toList();
  }

  Widget get getHintWidget => Text('Select Item',
      style: TextStyle(fontSize: 14, color: Theme.of(context).hintColor));
  List<String>? list1;
  List<String>? list2;
  String? value1;
  String? value2;
  @override
  void initState() {
    list1 = getNamesList(40);
    list2 = getNamesList(40);
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            const Text("default dropdown button"),
            DropdownButtonHideUnderline(
              child: DropdownButton(
                value: value1,
                onChanged: (value) {
                  value1 = value;
                  setState(() {});
                },
                hint: getHintWidget,
                items: getItems(list1!),
              ),
            ),
            const Text("open under button"),
            DropdownButtonHideUnderline(
              child: DropdownButton2<String>(
                hint: getHintWidget,
                items: getItems(list2!),
                value: value2,
                onChanged: (value) {
                  value2 = value;
                  setState(() {});
                },
                dropdownStyleData: DropdownStyleData(
                    maxHeight: MediaQuery.of(context).size.height * 0.3),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Thank you happy coding...

Top comments (0)