手动设置下拉按钮的值

时间:2019-11-23 20:30:33

标签: flutter drop-down-menu

我有两个小部件,它们是容器中的兄弟姐妹。一个小部件是自定义DropdownButton,另一个是自定义IconButton

父小部件:

static int _currentValue = 0;

Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Expanded(
          child: GCWDropDownButton(
            onChanged: (value) {
              setState(() {
                _currentValue = value;
              });
            }
          ),
        ),
        GCWIconButton(
          iconData: Icons.add,
          onPressed: () {
            print(_currentValue);
            setState(() {
              _currentValue++;
              //  <------------- how to set value to Dropdown Button
            });
          },
        ),
      ],
    );
  }

下拉小部件:

class GCWDropDownButton extends StatefulWidget {
  final Function onChanged;

  const GCWDropDownButton({Key key, this.onChanged}) : super(key: key);

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

class _GCWDropDownButtonState extends State<GCWDropDownButton> {

  int _dropdownValue = 1;

  @override
  Widget build(BuildContext context) {
    return Container(
      child: DropdownButton(
        value:_dropdownValue,
        icon: Icon(Icons.arrow_downward),
        onChanged: (newValue) {
          setState(() {
            _dropdownValue = newValue;
            widget.onChanged(newValue);
          });
        },
        items: ...
      ),
    );
  }
}

我想将DropdownButton的值更改为在按下IconButton之后增加。如果它是TextField,我会使用Controller

但是如何通过Dropdown实现呢?

1 个答案:

答案 0 :(得分:1)

您尝试将相同的值存储在2种不同的状态中:在父状态中,在子状态中。在您的情况下,最好在父母的状态下执行此操作,然后将当前值传递给孩子。

  int _currentIndex;

  @override
  Widget build(BuildContext context) {
...
        child: Row(
          children: <Widget>[
            Expanded(
              child: GCWDropDownButton(
                currentIndex: _currentIndex,
                onChanged: (index) {
                  setState(() {
                    _currentIndex = index;
                  });
                },
              ),
            ),
            GCWIconButton(
              iconData: Icons.add,
              onPressed: () {
                setState(() {
                  if (_currentIndex == null) {
                    _currentIndex = 0;
                  } else {
                    _currentIndex++;
                  }
                });
              },
            ),
          ],
        )
...

class GCWDropDownButton extends StatefulWidget {
  final Function onChanged;
  final int currentIndex;

  const GCWDropDownButton({Key key, this.onChanged, this.currentIndex}) : super(key: key);

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

class _GCWDropDownButtonState extends State<GCWDropDownButton> {
  @override
  Widget build(BuildContext context) {
    final values = ['one', 'two', 'three'];
    final currentValue = widget.currentIndex == null 
      ? null 
      : values[min(values.length - 1, widget.currentIndex)]; // Not going out of range

    return Container(
      child: DropdownButton(
        value: currentValue,
        icon: Icon(Icons.arrow_downward),
        onChanged: (newValue) {
          setState(() {
            widget.onChanged(values.indexOf(newValue));
          });
        },
        items: values.map((v) =>
          DropdownMenuItem(
            child: Text(v.toString()), 
            value: v, 
            key: Key(v.toString())
          )
        ).toList()
      ),
    );
  }
}

或者最好将DropdownButton和GCWIconButton放在一个有状态的小部件中,这样两个小部件共享相同的状态:

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: SafeArea(
        child: GCWDropDownButton()
      ),
    );
  }
}

class GCWDropDownButton extends StatefulWidget {
  @override
  _GCWDropDownButtonState createState() => _GCWDropDownButtonState();
}

class _GCWDropDownButtonState extends State<GCWDropDownButton> {
  int _currentIndex;

  final values = ['one', 'two', 'three'];

  @override
  Widget build(BuildContext context) {
    final currentValue = _currentIndex == null ? null  : values[_currentIndex];

    return Row(
      children: <Widget>[
        Expanded(
          child:Container(
            child: DropdownButton(
              value: currentValue,
              icon: Icon(Icons.arrow_downward),
              onChanged: (newValue) {
                setState(() {
                  _currentIndex = values.indexOf(newValue);
                });
              },
              items: values.map((v) =>
                DropdownMenuItem(
                  child: Text(v.toString()), 
                  value: v, 
                  key: Key(v.toString())
                )
              ).toList()
            ),
          ),
        ),
        IconButton(
          icon: Icon(Icons.add),
          onPressed: () {
            setState(() {
              if (_currentIndex == null) {
                _currentIndex = 0;
              } else 
              // Not going out of range
              if (_currentIndex != values.length - 1) {
                _currentIndex++;
              }
            });
          },
        ),
      ],
    );
  }
}