7

按下a 时PopupMenuButton,当前选定的值会突出显示,在此处输入图像描述

但是当DropdownButton按下 a 时,当前选择的值不会突出显示。 在此处输入图像描述

有没有办法突出 a 的选定值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'),
          ),
        ],
      ),
    );
  }
}

这是一个显示该问题的视频:

在此处输入图像描述

4

4 回答 4

2

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

但是,您可以添加一些内容,对 的child属性进行简单检查DropdownMenuItem,然后将子元素包装Text在其他内容中,或者在Text检查时设置元素本身的样式。

一个例子:

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

请注意,在实际情况下,您将有一个带有参数的方法来构建每个下拉项,因此验证不必像letter == 'A'.

这将是输出:

选定的输出示例

这种方法允许您稍微设置样式,但在某些情况下会产生丑陋的结果。虽然它是可定制的,但项目周围总会有一个白边,而且当下拉列表关闭时它也显示相同的样式,所以在主页上有点难看。

除了更改背景之外,您还可以更改文本颜色、下划线、侧面的图标,这样可以使它变得更好,例如:

DropdownMenuItem<String>(
  value: 'A',
  child: Text('The letter A',
    style: TextStyle(
      color: letter == 'A' ? Colors.red : Colors.black87,
    ),
  ),
)
于 2019-02-21T00:20:51.487 回答
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

在这里您可以看到 aInkwell是用于PopupMenuButton.

于 2019-02-20T19:15:52.350 回答
0

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

return Theme(
    data: ThemeData(highlightColor: Colors.grey[300]),
    child: DropdownButton()
于 2020-06-08T23:28:14.077 回答
0

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

每次打开时PopupMenuButton都会查看它的参数——与该值对应的项目将突出显示。每次使用该函数时initialValue:,您都需要更新参数。initialValueonSelected

确保父小部件是一个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;
    });
  }
}
于 2019-08-05T06:04:46.913 回答