Home > Software engineering >  How do I make the arrow icon face up when I expand the dropdown menu in flutter?
How do I make the arrow icon face up when I expand the dropdown menu in flutter?

Time:03-03

enter image description here

With the onTap method, I couldn't switch when I tapped a non-menu item with the drop-down menu open.

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

  @override
  Widget build(BuildContext context) {
    return DropdownButton2<String>(
      value: dropdownValue,
      buttonWidth: 100,
      onTap: (){
        setState(() {
          _arrowState = !_arrowState;
        });
      },
      icon: _arrowState ? const Icon(Icons.arrow_drop_down) : const Icon(Icons.arrow_drop_up),
      onChanged: (String? newValue) {
        setState(() {
          _arrowState = !_arrowState;
          dropdownValue = newValue!;
        });
      },
      items: <String>['One', 'Two', 'Free', 'Four']
          .map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
    );
  }
}

use plugin dropdown_button2: ^1.1.1

CodePudding user response:

Great suggestion! Use version ^1.2.0 I've added iconOnClick parameter to show different icon when menu open.

CodePudding user response:

Wrap your Icon widget with a RotationTransition and define a rotation animation like so:

class DropdownWidgetWrapper extends StatefulWidget {
  const DropdownWidgetWrapper({Key? key}) : super(key: key);

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

class _DropdownWidgetWrapperState extends State<DropdownWidgetWrapper> with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final Animation<double> _rotationAnimation;

  // Variable that
  bool _isDropdownOpen = false;

  @override
  void initState() {
    _controller = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    
    // The icon is animated from 0 degrees to a 
    // half turn = 180 degrees
    _rotationAnimation = Tween<double>(begin: 0, end: 0.5).animate(_controller);
    super.initState();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return RotationTransition(
      turns: _rotationAnimation,
      child: const Icon(Icons.keyboard_arrow_down),
    );
  }
}

Assuming you setState the variable _isDropdownOpen when the dropdown menu opens, in your onTap method you can include the following:

    if (_isDropdownOpen) {
      _controller.forward();
    } else {
      _controller.reverse();
    }
  • Related