flutter 在堆栈抖动上添加自定义下拉菜单

uinbv5nw  于 2023-01-21  发布在  Flutter
关注(0)|答案(1)|浏览(124)

我正在尝试添加一个自定义下拉菜单,其项目只是指向其他页面的链接
我尝试使用下拉按钮
但是我没能把它的元素做成一个链接,它需要一个值,而我没有一个值传递给它
谢谢

cunj1qz1

cunj1qz11#

在这种情况下,您可以使用OverlayEntry。下面是一个使用OverlayEntry的下拉列表的简单工作示例:

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

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

class _TestDropdownWidgetState extends State<TestDropdownWidget>
    with TickerProviderStateMixin {
  final LayerLink _layerLink = LayerLink();
  late OverlayEntry _overlayEntry;
  bool _isOpen = false;

  //Controller Animation
  late AnimationController _animationController;
  late Animation<double> _expandAnimation;

  @override
  void dispose() {
    super.dispose();
    _animationController.dispose();
  }

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 200),
    );
    _expandAnimation = CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeInOut,
    );
  }

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: _layerLink,
      child: InkWell(
        onTap: _toggleDropdown,
        child: Text('Click Me'), //Define your child here
      ),
    );
  }

  OverlayEntry _createOverlayEntry() {
    return OverlayEntry(
      builder: (context) => GestureDetector(
        onTap: () => _toggleDropdown(close: true),
        behavior: HitTestBehavior.translucent,
        // full screen container to register taps anywhere and close drop down
        child: SizedBox(
          height: MediaQuery.of(context).size.height,
          width: MediaQuery.of(context).size.width,
          child: Stack(
            children: [
              Positioned(
                left: 100,
                top: 100.0,
                width: 250,
                child: CompositedTransformFollower(
                  //use offset to control where your dropdown appears
                  offset: Offset(0, 20),
                  link: _layerLink,
                  showWhenUnlinked: false,
                  child: Material(
                    elevation: 2,
                    borderRadius: BorderRadius.circular(6),
                    borderOnForeground: true,
                    color: Colors.white,
                    child: Container(
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(6),
                        border: Border.all(color: Colors.grey),
                      ),
                      child: SizeTransition(
                        axisAlignment: 1,
                        sizeFactor: _expandAnimation,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.start,
                          crossAxisAlignment: CrossAxisAlignment.stretch,
                          children: [
                            //These are the options that appear in the dropdown
                            Text('Option 1'),
                            Text('Option 2'),
                            Text('Option 3'),
                            Text('Option 4'),
                            Text('Option 5'),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  void _toggleDropdown({
    bool close = false,
  }) async {
    if (_isOpen || close) {
      _animationController.reverse().then((value) {
        _overlayEntry.remove();
        if (mounted) {
          setState(() {
            _isOpen = false;
          });
        }
      });
    } else {
      _overlayEntry = _createOverlayEntry();
      Overlay.of(context)!.insert(_overlayEntry);
      setState(() => _isOpen = true);
      _animationController.forward();
    }
  }
}

这里有一个gif来显示用户界面:

相关问题