在DropdownButton中突出显示选定的值(例如PopupMenuButton)

时间:2019-02-20 19:04:43

标签: flutter

按下PopupMenuButton时,当前选择的值将突出显示,enter image description here

但是当按下DropdownButton时,当前选定的值不会突出显示。 enter image description here

是否可以突出显示DropdownButton的选定值?

作为参考,下面是一些示例代码:

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'),
          ),
        ],
      ),
    );
  }
}

以下是显示问题的视频:

enter image description here

4 个答案:

答案 0 :(得分:0)

据我所知,此灰色叠加层是材料设计库中的所谓“波纹效果”。似乎Flutter尚未在所有小部件中采用完整的设计。

但是,您可以尝试使用InkWell小部件将这种动画/颜色添加到当前小部件中:

https://flutter.io/docs/cookbook/gestures/ripples

例如:

PopupMenuItem<String>(
    value: 'B',
    child: InkWell(child: Text('The letter B'))
),

我不确定宽度是否正确,但是至少当您按条目时它应该显示灰色覆盖。

您还可以检查Flutter来源: https://github.com/flutter/flutter/blob/237fc2fb45639312001e947bf7465ef9f23bb699/packages/flutter/lib/src/material/popup_menu.dart#L933

在这里您可以看到Inkwell使用的是标准PopupMenuButton

答案 1 :(得分:0)

DropdownMenuItem不支持对子元素进行许多自定义修改,因为DropdownMenuItem属性中实际上没有样式,背景或任何东西可以帮助您。查看代码,它实际上并不是为此而构建的,

但是,您可以添加一些内容,只需对child的{​​{1}}属性进行检查,然后将DropdownMenuItem子元素包装成其他样式或设置{{1} }元素本身(如果已选中)。

一个例子:

Text

请注意,在实际情况下,您将拥有一个带有参数表的方法来构建每个下拉项,因此验证不必像Text那样进行硬编码。

这将是输出:

selected output 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'),
            ),
          ),
        ],
      ),
    );
}

答案 2 :(得分:0)

您的原始问题是:“ 当显示所有值时,我对当前所选值的较暗背景感兴趣。

您的initialValue:每次打开时都会查看其initialValue参数-与该值对应的项目将突出显示。您每次都需要使用onSelected函数来更新StatefulWidget参数。

确保父窗口小部件是initialValue小部件,并创建对PopupMenuButton的引用。 onSelected有一个String参数,该参数带有一个带有参数PopupMenuButton的函数。

每当您从setState(() { ... this.initialValue = value; }); 中选择一个选项时,请致电

Class YourClass extends StatefulWidget {
  @override
  createState() => _YourClassState();
}

class _YourClassState extends State<YourClass> {
  ...
  String initialValue = 'foo';

  @override
  Widget build(BuildContext context) {
    final items = [
      PopupMenuItem(
        value: 'foo',
        child: Text('foo'),
      ),
      PopupMenuItem(
        value: 'nice',
        child: Text('nice'),
      ),
    }
    return Scaffold(
      appBar: ...,
      drawer: ...,
      body: PopupMenuButton(
        icon: ...,
        itemBuilder: (_) => items,
        initialValue: this.initialValue,
        onSelected: (value) => bar(value),
      ),
    );
  }

  void bar(String value) {
    setState(() {
      ...
      this.initialValue = value;
    });
  }
}

完整的类看起来像这样。

console.log("2Nd STATE "+this.state)

答案 3 :(得分:0)

您可以用Theme包装小部件以设置突出显示的颜色。

return Theme(
    data: ThemeData(highlightColor: Colors.grey[300]),
    child: DropdownButton()