Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make the shape of the list created by a dropdown button circular?

I have a dropdown button and it has rounded edges. Now, how do I make the list which pops up when the dropdown is clicked have rounded edges as well ?

Image of dropdown:

enter image description here

Image of list which pops up when dropdown is clicked (I want to make these edges rounded like my dropdown button):

enter image description here

My code:

return Theme(
  data: ThemeData(canvasColor: cardBlueColor, brightness: Brightness.dark),
  child:Container(
    width:MediaQuery.of(context).size.width/1.25,
    child:Card(
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
      color: cardBlueColor,
      elevation: 8.0,
      child:DropdownButtonHideUnderline(
        child: ButtonTheme(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0)),
          alignedDropdown: true,
          child: DropdownButton(
            elevation: 8,
            icon: Icon(Icons.keyboard_arrow_down),
            value: _dateSelected,
            hint: AutoSizeText(NA_FLIGHT_PAGE_DROPDOWN, style: TextStyle(color: white,),textAlign: TextAlign.center,),
            isDense: false,
            onChanged: (String newValue){
              setState(() {
                _dateSelected = newValue;
                dropdownMap = _getDropdownMap(snapshot);     
              });
            },
            items: dropdownList.map((key){
              return DropdownMenuItem<String>(
                value: key.toString(),
                child: AutoSizeText(key.toString(), style: TextStyle(color: white,),textAlign: TextAlign.center,),
              );
            }).toList(),
          ),
        ),
      )
    )
  )
);

What I've tried:

// adding a shape to the button theme
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.0))
// using a container with radius and making canvas transparent
data: ThemeData(canvasColor: transparent, brightness: Brightness.dark),

// omitted code

  return DropdownMenuItem<String>(
    value: key.toString(),
    child: Container(
      decoration: BoxDecoration(color:cardBlueColor, borderRadius: BorderRadius.all(Radius.circular(10))),
      child: AutoSizeText(key.toString(), style: TextStyle(color: white,),textAlign: TextAlign.center,),
    ) 
  );

Image of container with transparent canvas color method as suggested:

enter image description here

like image 834
Rajdeep Avatar asked Jun 28 '19 10:06

Rajdeep


2 Answers

First I think you'll need to change your ThemeData.canvasColor to transparent. Then try something along the lines of this:

    items: <DropdownMenuItem>[
      DropdownMenuItem(
        child: Container(
          decoration: BoxDecoration(
            color: Colors.green,
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(15.0),
              topRight: Radius.circular(15.0),
            ),
          ),
        ),
      ),
      DropdownMenuItem(
        child: Container(
          decoration: BoxDecoration(
            color: Colors.green,
          ),
        ),
      ),
      DropdownMenuItem(
        child: Container(
          decoration: BoxDecoration(
          color: Colors.green,
          borderRadius: BorderRadius.only(
            bottomLeft: Radius.circular(15.0),
            bottomRight: Radius.circular(15.0),
          ),
        ),
      ),
    ),
  ],

So the first item is rounded at the top and the last one is rounded at the bottom, there is probably a more elegant way of doing this but it should work same.

like image 149
Jack Hopkins Avatar answered Sep 17 '22 18:09

Jack Hopkins


I was able to create rounded corners for the dropdown menu list like this,

like this.

Here's how I did it,

I copied Dropdown widget code from Flutter Material package added ClipRRect to _DropdownMenu widget's build method.

you can download this file in your repository and change code from line 270 to line 302 to this

child: ClipRRect(
        borderRadius: BorderRadius.all(Radius.circular(20)),
        child: CustomPaint(
          painter: _DropdownMenuPainter(
            color: widget.dropdownColor ?? Theme.of(context).canvasColor,
            elevation: route.elevation,
            selectedIndex: route.selectedIndex,
            resize: _resize,
            // This offset is passed as a callback, not a value, because it must
            // be retrieved at paint time (after layout), not at build time.
            getSelectedItemOffset: () =>
                route.getItemOffset(route.selectedIndex),
          ),
          child: Semantics(
            scopesRoute: true,
            namesRoute: true,
            explicitChildNodes: true,
            label: localizations.popupMenuLabel,
            child: Material(
              type: MaterialType.transparency,
              textStyle: route.style,
              child: ScrollConfiguration(
                behavior: const _DropdownScrollBehavior(),
                child: Scrollbar(
                  child: ListView(
                    controller: widget.route.scrollController,
                    padding: kMaterialListPadding,
                    shrinkWrap: true,
                    children: children,
                  ),
                ),
              ),
            ),
          ),
        ),
      ),

also delete the imports from line 15 to line 26 and add this line

import 'package:flutter/material.dart'
hide
    DropdownButton,
    DropdownButtonFormField,
    DropdownButtonHideUnderline,
    DropdownMenuItem;

make sure you set BorderRadius to your desired size, if you wanted make circular list then take a look at ClipOval and change ClipRRect to ClipOval.

also make sure you hide the Dropdown or other relevant widgets from package:flutter/material.dart when you import this Dropdown widget from this modified file.

like image 20
Yashawant Avatar answered Sep 16 '22 18:09

Yashawant