How to Create a Custom Dropdown Color Menu in Flutter

 Dropdown menus are a common UI component in Flutter, but sometimes you need something more personalized to fit your app’s design. This tutorial walks you through creating a custom dropdown color menu in Flutter. You’ll learn how to display color options in a dropdown and allow users to select one, with the selected color updating the UI dynamically.

Step 1: Setting Up the Flutter Project

    1. Create a new Flutter project or open an existing one:
flutter create custom_dropdown_menu
cd custom_dropdown_menu

    2. Open the project in your favorite IDE (e.g., VS Code or Android Studio).

Step 2: Building the Color Dropdown Menu

To create a dropdown menu that displays color options, we’ll use Flutter’s DropdownButton widget. However, we’ll customize it to show color swatches instead of regular text.

Code: Custom Dropdown Color Menu

Below is the full implementation:

import 'package:flutter/material.dart';

void main() {
  runApp(ColorDropdownApp());
}

class ColorDropdownApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ColorDropdownScreen(),
    );
  }
}

class ColorDropdownScreen extends StatefulWidget {
  @override
  _ColorDropdownScreenState createState() => _ColorDropdownScreenState();
}

class _ColorDropdownScreenState extends State<ColorDropdownScreen> {
  // List of colors for the dropdown
  final List<Color> colors = [
    Colors.red,
    Colors.green,
    Colors.blue,
    Colors.yellow,
    Colors.purple,
    Colors.orange,
  ];

  // Currently selected color
  Color selectedColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Dropdown Color Menu'),
        backgroundColor: selectedColor,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Select a Color:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            // Dropdown Button
            DropdownButton<Color>(
              value: selectedColor,
              icon: Icon(Icons.arrow_drop_down),
              iconSize: 24,
              elevation: 16,
              dropdownColor: Colors.white,
              style: TextStyle(color: Colors.black),
              onChanged: (Color? newColor) {
                setState(() {
                  selectedColor = newColor!;
                });
              },
              items: colors.map<DropdownMenuItem<Color>>((Color color) {
                return DropdownMenuItem<Color>(
                  value: color,
                  child: Container(
                    width: 100,
                    height: 20,
                    color: color,
                  ),
                );
              }).toList(),
            ),
            SizedBox(height: 40),
            // Display selected color
            Text(
              'You selected:',
              style: TextStyle(fontSize: 18),
            ),
            Container(
              width: 100,
              height: 100,
              color: selectedColor,
            ),
          ],
        ),
      ),
    );
  }
}


Step 3: Running the Application

    1. Save the code to main.dart.
    2. Run the application
flutter run


Output

How It Works

    1. DropdownButton Widget:

  • Displays a list of color options in a dropdown menu.
  • The DropdownButton widget has items, which is a list of DropdownMenuItem widgets. Each menu item contains a Container filled with a color swatch.

    2. Dynamic State Update:

  • The onChanged callback updates the selectedColor variable whenever a new color is chosen, triggering a rebuild of the widget tree to reflect the updated color.
    3. Selected Color Preview:
  • The selected color is displayed in a square box below the dropdown.

Code Enhancement

Let's enhance the custom dropdown menu to use a List<Map<String, dynamic>> instead of List<Color>. This allows us to associate a name with each color, making the menu more informative and flexible.

Updated Code: Custom Dropdown with Color Names

Here’s the enhanced version of the code:

import 'package:flutter/material.dart';

void main() {
  runApp(ColorDropdownApp());
}

class ColorDropdownApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: ColorDropdownScreen(),
    );
  }
}

class ColorDropdownScreen extends StatefulWidget {
  @override
  _ColorDropdownScreenState createState() => _ColorDropdownScreenState();
}

class _ColorDropdownScreenState extends State<ColorDropdownScreen> {
  // List of colors with names
  final List<Map<String, dynamic>> _colors = [
    {'name': 'Red', 'color': Colors.red},
    {'name': 'Green', 'color': Colors.green},
    {'name': 'Blue', 'color': Colors.blue},
    {'name': 'Yellow', 'color': Colors.yellow},
    {'name': 'Purple', 'color': Colors.purple},
    {'name': 'Orange', 'color': Colors.orange},
  ];

  // Currently selected color
  Map<String, dynamic> _selectedColor = {'name': 'Red', 'color': Colors.red};
  String _selectedColorName = 'Red';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Enhanced Dropdown Color Menu'),
        backgroundColor: _selectedColor['color'],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Select a Color:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            // Dropdown Button
            Container(
              // Set the background color of the container dynamically
              decoration: BoxDecoration(
                color: _selectedColor['color'],
                borderRadius: BorderRadius.circular(8.0),
              ),
              padding: EdgeInsets.symmetric(horizontal: 8.0),

              child: DropdownButtonHideUnderline(
                child: DropdownButton<String>(
                  // Define the dropdown items
                  items: _colors.map((colorMap) {
                    return DropdownMenuItem<String>(
                      value: colorMap['name'],
                      child: Row(
                        children: [
                          Container(
                            width: 20,
                            height: 20,
                            color: colorMap['color'], // Display color preview
                            margin: const EdgeInsets.only(right: 8),
                          ),
                          Text(colorMap['name']),
                        ],
                      ),
                    );
                  }).toList(),
                  // Hint text
                  hint: Text(
                    _selectedColorName,
                    style: TextStyle(color: Colors.white),
                  ),
                  onChanged: (String? selectedName) {
                    setState(() {
                      _selectedColorName = selectedName!;
                      // Update background color based on the selected color
                      _selectedColor = _colors.firstWhere((element) => element['name'] == selectedName);
                    });
                  },
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}


Output of the enhanced code




Explanation of Enhancements

1. Using List<Map<String, dynamic>>:

  • Each color is represented as a map with name and color keys:
{'name': 'Red', 'color': Colors.red}


2. Updated _selectedColor State:

  • The dropdown now holds a map for the selected color:
Map<String, dynamic> _selectedColor = {'name': 'Red', 'color': Colors.red};

3. Wrapped DropdownButton with the container and removed the underline.

  • Once the selected color menu is changed then the container background will be updated.

Container(
  // Set the background color of the container dynamically
  decoration: BoxDecoration(
    color: _selectedColor['color'],
    borderRadius: BorderRadius.circular(8.0),
  ),
  padding: EdgeInsets.symmetric(horizontal: 8.0),
  child: DropdownButtonHideUnderline( child: ...),
),

4. Custom DropdownMenuItem:

  • Each menu item displays a small color swatch alongside the color name using a Row widget:
 return DropdownMenuItem<String>(
  value: colorMap['name'],
  child: Row(
	children: [
	  Container(
		width: 20,
		height: 20,
		color: colorMap['color'], // Display color preview
		margin: const EdgeInsets.only(right: 8),
	  ),
	  Text(colorMap['name']),
	],
  ),
);

5. Dynamic Updates:

  • When a new color is selected, the onChanged callback updates _selectedColor, triggering a UI refresh to reflect the selected color and its name.

How It Works

  • The dropdown uses the _colors list to generate menu items.
  • Each menu item is a combination of a color swatch and the color name.
  • When the user selects a color, the onChanged callback updates _selectedColor.
  • The app bar and the color preview box update dynamically based on the selected color.


This enhancement adds functionality and improves the user experience by displaying both color swatches and names in the dropdown menu. Using List<Map> makes the implementation more flexible and extendable. You can now easily add more properties (e.g., hex codes, descriptions) to the colors if needed.

You can explore the source code on the Github repository.

GitHub Logo View on GitHub
أحدث أقدم

نموذج الاتصال