简体   繁体   English

在 flutter 中的 DropDownButton(展开)左侧添加图标

[英]Adding icon to left of DropDownButton (expanded) in flutter

I want to add icon to left of DropDownButton but can't find a way to do so.我想在DropDownButton的左侧添加图标,但找不到这样做的方法。 What I want to achieve is like this:我想要实现的是这样的:

在此处输入图像描述

I have tried following code but it places icon to right where I don't want it and it also overrides arrow icon:我尝试了以下代码,但它将图标放在我不想要的地方,它还覆盖了箭头图标:

 `@override
  Widget build(BuildContext context) {
  return Scaffold(
  body: Container(
    margin: EdgeInsets.only(top: 64.0, left: 16.0, right: 16.0),
    color: Colors.white,
    child: DropdownButton(
      icon: Icon(
        Icons.person,
        color: Colors.redAccent,
        size: 20.09,
      ),
      isExpanded: true,
      items: _studentList.map((val) {
        return DropdownMenuItem(
          value: val,
          child: Text(val),
        );
      }).toList(),
      value: _currentSelectedItem,
      onChanged: (value) {
        setState(() {
          _currentSelectedItem = value;
        });
      },
    ),
  ),
);
  }`

Output of above code is like this:上述代码的 Output 是这样的:

在此处输入图像描述

I have also tried to place Icon() and DropDownButton() inside Row() widget but that does not allow the DropDownButton() to expand to full width.我还尝试将Icon()DropDownButton()放在Row()小部件内,但这不允许DropDownButton()扩展到全宽。

Any help would be appreciated.任何帮助,将不胜感激。

Thanks谢谢

There is no specific attribute for adding icon the way you want but you can always work around your code and find some tweaks.没有以您想要的方式添加图标的特定属性,但您始终可以解决您的代码并找到一些调整。 Use the following code which will place you Icon() on top of your DropDownButton() button.使用以下代码将Icon()放在DropDownButton()按钮的顶部。

@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
  children: <Widget>[
    Container(
      decoration: BoxDecoration(
        color: Colors.white,
        boxShadow: [
          BoxShadow(
            color: Colors.grey,
            blurRadius: 20.0,
            spreadRadius: 0.5,
            offset: Offset(1.0, 1.0),
          ),
        ],
      ),
      padding: EdgeInsets.only(left: 44.0),
      margin: EdgeInsets.only(top: 64.0, left: 16.0, right: 16.0),
      child: DropdownButton(
        isExpanded: true,
        items: your_list.map(
          (val) {
            return DropdownMenuItem(
              value: val,
              child: Text(val),
            );
          },
        ).toList(),
        value: _currentSelectedItem,
        onChanged: (value) {
          setState(() {
            _currentSelectedItem = value;
          });
        },
      ),
    ),
    Container(
      margin: EdgeInsets.only(top: 80.0, left: 28.0),
      child: Icon(
        Icons.person,
        color: Colors.redAccent,
        size: 20.0,
      ),
    ),
  ],
),
  );
}

Use DropdownButtonFormField as it has decoration property.使用DropdownButtonFormField因为它具有装饰属性。 You can use prefixIcon attribute to set icon on left side.您可以使用prefixIcon属性在左侧设置图标。

Example:例子:

DropdownButtonFormField<String>(
         decoration: InputDecoration(
         prefixIcon: Icon(Icons.person),
         ),
         hint: Text('Please choose account type'),
         items: <String>['A', 'B', 'C', 'D'].map((String value) {
         return DropdownMenuItem<String>(
         value: value,
         child: new Text(value),
       );
      }).toList(),
     onChanged: (_) {},
),

Result:结果:

在此处输入图像描述

Remember, everything is a widget, so:请记住,一切都是小部件,因此:

iconSize: 0,
hint: Row(
         children: [
            Container(
                child: Text('Freguesias'),
            ),
            Container(
                child: Icon(Icons.arrow_drop_down),
            ),
          ],
 ),

If the icon really should be visually part of the DropDown component, you could go the following route.如果该图标确实应该是 DropDown 组件的视觉部分,您可以 go 以下路线。 Its a bit hacky and lacks being responsive but its a start for some more experiments.它有点hacky并且缺乏响应性,但它是更多实验的开始。 I added a complete working example so you can copy paste it to a runnable main dart file.我添加了一个完整的工作示例,因此您可以将其复制粘贴到可运行的主 dart 文件中。

In a nutshell, it uses a Stack layout so the icon is just placed over the dropdown component.简而言之,它使用 Stack 布局,因此图标只是放置在下拉组件上。 Then i padded the Text so that there is space to the left.然后我填充了文本,以便左侧有空间。

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

/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: MyStatefulWidget(),
      ),
    );
  }
}

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

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

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  String dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Stack(
          children: <Widget>[
            DropdownButton<String>(
              value: dropdownValue,
              //icon: Icon(Icons.arrow_downward),
              iconSize: 24,
              elevation: 16,
              style: TextStyle(color: Colors.deepPurple),
              underline: Container(
                height: 2,
                color: Colors.deepPurpleAccent,
              ),
              onChanged: (String newValue) {
                setState(() {
                  dropdownValue = newValue;
                });
              },
              items: <String>['One', 'Two', 'Free', 'Four']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Padding(
                    padding: const EdgeInsets.only(left: 30.0),
                    child: Text("$value"),
                  ),
                );
              }).toList(),
            ),
            Container(
                margin: EdgeInsets.symmetric(vertical: 10),
                child: Icon(Icons.arrow_downward)),
          ],
        ),
      ),
    );
  }
}

This may too late.这可能为时已晚。 But will helpful for upcoming viewers.但对即将到来的观众会有帮助。

Instead of using DropDownButton , we can use DropDownButtonFormField .我们可以使用DropDownButtonFormField代替DropDownButton Which has a decoration property.其中具有装饰属性。 With this we can make use of prefixIcon property to add icon to the left side of DropDownButton:有了这个,我们可以利用prefixIcon属性将图标添加到 DropDownButton 的左侧:

DropDownButtonFormField(
  decoration: InputDecoration(
    prefixIcon: Icon(Icons.person, color: Colors.redAccent),
  ),
  ...
);

Wrapping your icon and dropdown widget inside a row widget, nested inside a container will do the work like below:将您的图标和下拉小部件包装在一个行小部件内,嵌套在一个容器内,将执行如下工作:

body: Container(
    margin: EdgeInsets.only(top: 64.0, left: 16.0, right: 16.0),
    color: Colors.white,
    child: 
    child: Row(
    children: <Widget>[
      Icon(
        Icons.person,
        color: Colors.redAccent,
        size: 20.09,
     ),
     Expanded(
        flex:1,
        child:DropdownButton(
            isExpanded: true,
            items: _studentList.map((val) {
            return DropdownMenuItem(
              value: val,
              child: Text(val),
            );
        }).toList(),
        value: _currentSelectedItem,
        onChanged: (value) {
         setState(() {
           _currentSelectedItem = value;
         });
      },
     ),
    )
  ]  
)

Simple way to do this would be to pass child prop to DropdownMenuItem, you can then pass any widget, i have created a row and passed the icon and text in the row:执行此操作的简单方法是将子道具传递给 DropdownMenuItem,然后您可以传递任何小部件,我创建了一行并传递了该行中的图标和文本:

items: <String>['George Green School', 'George Blue School', 'George Red School', 'George Yellow School']
                .map<DropdownMenuItem<String>>((String value) {
              return DropdownMenuItem<String>(
                value: value,
                child: Row(
                  children: [
                    Icon(Icons.dangerous),
                    Text(value, style: TextStyle(fontSize : 12),),
                  ],
                ),
              );
            }).toList(),

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM