首页 > 解决方案 > 有没有办法在颤动中制作漂亮的下拉菜单?

问题描述

我想做这样漂亮的下拉菜单。我已经尝试过用容器制作它,但这需要很长时间。是否有任何包或配置默认下拉菜单和项目的方法?

在此处输入图像描述

标签: flutterdrop-down-menu

解决方案


尝试这个:

import 'package:flutter/material.dart';

void main() => runApp(ExampleApp());

class ExampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: PopMenu(),
    );
  }
}

class PopMenu extends StatefulWidget {
  @override
  _PopMenuState createState() => _PopMenuState();
}

class _PopMenuState extends State<PopMenu> {
  List<String> _menuList = ['menu 1', 'menu 2', 'menu 3'];
  GlobalKey _key = LabeledGlobalKey("button_icon");
  OverlayEntry _overlayEntry;
  Offset _buttonPosition;
  bool _isMenuOpen = false;

  void _findButton() {
    RenderBox renderBox = _key.currentContext.findRenderObject();
    _buttonPosition = renderBox.localToGlobal(Offset.zero);
  }

  void _openMenu() {
    _findButton();
    _overlayEntry = _overlayEntryBuilder();
    Overlay.of(context).insert(_overlayEntry);
    _isMenuOpen = !_isMenuOpen;
  }

  void _closeMenu() {
    _overlayEntry.remove();
    _isMenuOpen = !_isMenuOpen;
  }

  OverlayEntry _overlayEntryBuilder() {
    return OverlayEntry(
      builder: (context) {
        return Positioned(
          top: _buttonPosition.dy + 70,
          left: _buttonPosition.dx,
          width: 300,
          child: _popMenu(),
        );
      },
    );
  }

  Widget _popMenu() {
    return Material(
      child: Container(
        width: 300,
        height: 300,
        decoration: BoxDecoration(
          color: Color(0xFFF67C0B9),
          borderRadius: BorderRadius.circular(4),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: List.generate(
            _menuList.length,
            (index) {
              return GestureDetector(
                onTap: () {},
                child: Container(
                  alignment: Alignment.center,
                  width: 300,
                  height: 100,
                  child: Text(_menuList[index]),
                ),
              );
            },
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          key: _key,
          width: 300,
          height: 50,
          decoration: BoxDecoration(
            color: Color(0xFFF5C6373),
            borderRadius: BorderRadius.circular(25),
          ),
          child: Row(
            children: [
              Expanded(
                child: Center(child: Text('menu 1')),
              ),
              IconButton(
                icon: Icon(Icons.arrow_downward),
                color: Colors.white,
                onPressed: () {
                  _isMenuOpen ? _closeMenu() : _openMenu();
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

推荐阅读