Home > Software design >  How to Add Different Icons to DropdownMenu Items in Flutter?
How to Add Different Icons to DropdownMenu Items in Flutter?

Time:11-05

How to add different icons for each DropdownMenu item? I want to add different icons for each DropdownMenu item. Before text. How to implement with DropdownMenu or any other way. Like this:

Before click

Menu item before click

After click

After click

import 'package:flutter/material.dart';

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

class MainApp extends StatefulWidget {
  MainApp({super.key});

  @override
  State<MainApp> createState() => _MainAppState();
}

class _MainAppState extends State<MainApp> {
  var list = ['One', 'Two', 'Three', 'Four'];
  late String dropdownValue = list.first;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: DropdownMenu(
            initialSelection: list.first,
            onSelected: (String? value) {
              setState(() {
                dropdownValue = value!;
              });
            },
            dropdownMenuEntries:
                list.map((String value) {
              return DropdownMenuEntry(value: value, label: value);
            }).toList(),
          ),
        ),
      ),
    );
  }
}

CodePudding user response:

DropdownMenuEntry takes a Widget? leadingIcon & Widget? trailingIcon. Try adding the icons to your list. Maybe as a map or as a class like so:

  1. Declare a class
class CustomObject {
  final String label;
  final Widget? leadingIcon;

  CustomObject({
    required this.label,
    this.leadingIcon,
  });
}
  1. Declare a list to put in the dropdown
List<CustomObject> list = [
  CustomObject(label: 'One', leadingIcon: const Icon(Icons.square)),
  CustomObject(label: 'Two', leadingIcon: const Icon(Icons.circle)),
  CustomObject(label: 'Three', leadingIcon: const Icon(Icons.rectangle)),
];
  1. Declare a late object in a StatefulWidget to set the selected meny entry to
late CustomObject currentObject;
  1. Set current object at initState method. This would also work for in case there was a previous selection saved somewhere, it should set be set here.
@override
void initState() {
  super.initState();
  currentObject = list.first;
}
  1. Use it at the DropdownMenu like so:
DropdownMenu(
  initialSelection: currentObject,
  leadingIcon: currentObject.leadingIcon,
  onSelected: (value) {
    setState(() {
      currentObject = value!;
    });
  },
  dropdownMenuEntries: list.map((CustomObject object) {
    return DropdownMenuEntry(
      value: object,
      label: object.label,
      leadingIcon: object.leadingIcon,
      trailingIcon: object == currentObject ? const Icon(Icons.check) : null,
    );
  }).toList(),
)

What it looks like

enter image description here

CodePudding user response:

Use items parameter in DropdownMenu and use DropDownMenuItem in it. Then DropDownMenuItem Accepts a child paramter. In that you can use any widget.So, use a row and place a icon and then text

CodePudding user response:

This works for you

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

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  List<Map> list = [
    {
      'value': '1',
      'label': 'One',
      'leadingIcon': 'assets/svg/One.svg',
    },
    {
      'value': '2',
      'label': 'Two',
      'leadingIcon': 'assets/svg/Two.svg',
    },
    {
      'value': '3',
      'label': 'Three',
      'leadingIcon': 'assets/svg/Three.svg',
    },
  ];
  late String dropdownValue = list.first['value'];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: DropdownMenu<String>(
          initialSelection: list.first['value'],
          onSelected: (String? value) {
            setState(() {
              dropdownValue = value!;
            });
          },
          dropdownMenuEntries: list
              .map((e) => DropdownMenuEntry<String>(
                    value: e['value'] as dynamic,
                    label: e['label'] as String,
                    leadingIcon: SvgPicture.asset(
                      e['leadingIcon'] as String,
                      width: 24,
                      height: 24,
                    ),
                  ))
              .toList(),
        ),
      ),
    );
  }
}

It will look like this

  • Related