Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Highlight selected value in DropdownButton (like PopupMenuButton)

When a PopupMenuButton is pressed, the currently selected value is highlighted, enter image description here

but when a DropdownButton is pressed, the currently selected value is not highlighted. enter image description here

Is there a way to highlight the selected value of a DropdownButton?

For reference here is some sample code:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: MyHomePage());
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String letter = 'A';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Popup Menu Button')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          SizedBox(height: 16.0),
          Text('PopupMenuButton'),
          buildPopupMenuButton(),
          SizedBox(height: 16.0),
          Text('DropdownButton'),
          buildDropdownButton(),
        ],
      ),
    );
  }

  Widget buildPopupMenuButton() {
    return PopupMenuButton<String>(
      padding: EdgeInsets.zero,
      initialValue: letter,
      onSelected: (val) => setState(() => letter = val),
      child: ListTile(
        title: Text('The letter $letter'),
      ),
      itemBuilder: (BuildContext context) {
        return <PopupMenuItem<String>>[
          PopupMenuItem<String>(
            value: 'A',
            child: Text('The letter A'),
          ),
          PopupMenuItem<String>(
            value: 'B',
            child: Text('The letter B'),
          ),
        ];
      },
    );
  }

  Widget buildDropdownButton() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      child: DropdownButton<String>(
        value: letter,
        onChanged: (val) => setState(() => letter = val),
        items: [
          DropdownMenuItem<String>(
            value: 'A',
            child: Text('The letter A'),
          ),
          DropdownMenuItem<String>(
            value: 'B',
            child: Text('The letter B'),
          ),
        ],
      ),
    );
  }
}

Here's a video that shows the issue:

enter image description here

like image 425
Simpler Avatar asked Feb 20 '19 19:02

Simpler


People also ask

How do you get the selected option value in flutter?

Step 1: Add a variable called dropdownValue that holds the currently selected item. Step 2: Add the DropdownButton widget to your page. Step 3: Inside the DropdownButton, add the value parameter and assign the dropdownValue that we created in step 1.

How do I use DropdownButton in flutter?

DropDownButton: In Flutter, A DropDownButton is a material design button. The DropDownButton is a widget that we can use to select one unique value from a set of values. It lets the user select one value from a number of items. The default value shows the currently selected value.

How do I open dropdown dialog below DropdownButton?

Option 1: Set DropDown. dart selectedItemOffset to -40 in then DropDownItems will always opens below the DropdownButton .


1 Answers

The DropdownMenuItem doesn't support many custom modifications on the child element, as there's no style, background, anything actually in the DropdownMenuItem attributes to help you with that. Looking at the code, it really wasn't built for that,

Yet, there's something you could add, a simple check on the child attribute of the DropdownMenuItem, and wrap the Text child element in something else or style the Text element itself if it is checked.

One example:

Widget buildDropdownButton() {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16.0),
      child: DropdownButton<String>(
        value: letter,
        onChanged: (val) => setState(() => letter = val),
        items: [
          DropdownMenuItem<String>(
            value: 'A',
            child: Container(
              color: letter == 'A' ? Colors.black12 : null,
              child: Text('The letter A'),
            ),
          ),
          DropdownMenuItem<String>(
            value: 'B',
            child: Container(
              color: letter == 'B' ? Colors.black12 : null,
              child: Text('The letter B'),
            ),
          ),
        ],
      ),
    );
}

Note that in a real case scenario, you would have a method with a paremeter to build each dropdown item, so the verification wouldn't have to be hardcoded like letter == 'A'.

This would be the output:

selected output example

This approach allows you to style a bit, but it has an ugly result in some cases. Although it is customizable, there will always be a white margin around the item, and it also shows the same styles when the dropdown list is closed, so it gets a bit ugly on the main page.

Instead of changing the background, you can also change text colors, underline, icons on the side, something like that make it much better, like:

DropdownMenuItem<String>(
  value: 'A',
  child: Text('The letter A',
    style: TextStyle(
      color: letter == 'A' ? Colors.red : Colors.black87,
    ),
  ),
)
like image 200
George Avatar answered Oct 16 '22 18:10

George