Flutter tạo menu Facebook đơn giản

Oct 27 2020

Khi Fluttertôi đang cố tạo một Facebookmenu đơn giản , trong ảnh chụp màn hình bên dưới, chúng tôi có tiện ích con số một và khi tôi nhấp vào đó, tiện ích con nằm bên dưới tiện ích con hiện tại, sẽ được thay đổi kích thước và lớn lên và hiển thị các biểu tượng khác vào đó

mã dưới đây mà tôi đã giới thiệu tham chiếu hoạt động tốt, nhưng nó không có vùng chứa nền

trong tham chiếu liên kết Columnđược sử dụng và tôi đã thay đổi nó thành Stackvà không hoạt động chính xác

tài liệu tham khảo

import 'package:flutter/material.dart';

class FancyFab extends StatefulWidget {
  final Function() onPressed;
  final String tooltip;
  final IconData icon;

  FancyFab({this.onPressed, this.tooltip, this.icon});

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

class _FancyFabState extends State<FancyFab>
    with SingleTickerProviderStateMixin {
  bool isOpened = false;
  AnimationController _animationController;
  Animation<Color> _buttonColor;
  Animation<double> _animateIcon;
  Animation<double> _translateButton;
  Curve _curve = Curves.easeOut;
  double _fabHeight = 56.0;

  @override
  initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500))
          ..addListener(() {
            setState(() {});
          });
    _animateIcon =
        Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
    _buttonColor = ColorTween(
      begin: Colors.blue,
      end: Colors.red,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.00,
        1.00,
        curve: Curves.linear,
      ),
    ));
    _translateButton = Tween<double>(
      begin: _fabHeight,
      end: -14.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.0,
        0.75,
        curve: _curve,
      ),
    ));
    super.initState();
  }

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

  animate() {
    if (!isOpened) {
      _animationController.forward();
    } else {
      _animationController.reverse();
    }
    isOpened = !isOpened;
  }

  Widget add() {
    return Container(
      child: FloatingActionButton(
        onPressed: null,
        tooltip: 'Add',
        child: Icon(Icons.add),
      ),
    );
  }

  Widget image() {
    return Container(
      child: FloatingActionButton(
        onPressed: null,
        tooltip: 'Image',
        child: Icon(Icons.image),
      ),
    );
  }

  Widget inbox() {
    return Container(
      child: FloatingActionButton(
        onPressed: null,
        tooltip: 'Inbox',
        child: Icon(Icons.inbox),
      ),
    );
  }

  Widget toggle() {
    return Container(
      child: FloatingActionButton(
        backgroundColor: _buttonColor.value,
        onPressed: animate,
        tooltip: 'Toggle',
        child: AnimatedIcon(
          icon: AnimatedIcons.menu_close,
          progress: _animateIcon,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value * 3.0,
            0.0,
          ),
          child: add(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value * 2.0,
            0.0,
          ),
          child: image(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value,
            0.0,
          ),
          child: inbox(),
        ),
        toggle(),
      ],
    );
  }
}

Tôi muốn sử dụng tiện ích này vào Flutterlistview, tiện ích đó sẽ xuất hiện ở nơi tôi nhấp vào, ví dụ bạn cho rằng tôi có tôi IconButtonvào ListViewcác mục, khi tôi nhấp vào đó, tiện ích này sẽ xuất hiện ở vị trí được nhấp và ButtonphảiFloatingActionButton

Trả lời

4 AnasMohammed Oct 29 2020 at 20:47

Tôi đã thực hiện điều này bằng cách sử dụng StackAnimatedContainer.

  • sử dụng Positionedtrong Stack, tôi đã đặt nó ở dưới cùng. Lý do cho điều này là để căn chỉnh cả hai ContainerFABcùng một vị trí khi hoạt ảnh của nó.
  • bằng cách sử dụng AnimatedContainer, tôi đã tạo một hoạt ảnh đơn giản thay đổi chiều cao của nó khi chúng ta nhấn vào FABbằng cách sử dụng giá trị bool.

(Tôi Thêm một vùng chứa bổ sung vào cột, nó sẽ ẩn sau FAB và cũng Căn chỉnh nó một cách hoàn hảo, nhưng bạn có thể thêm SizedBox hoặc Vùng chứa mà không có màu và giữ kích thước cuối cùng là 54.0, nếu bạn không sử dụng list.generate)

Hãy thử điều này trên DartPad

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
            child: Container(
          width: 250,
          height: 250,
          color: Colors.white,
          child: YellowBird(),
        )),
      ),
    );
  }
}

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

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

class _YellowBirdState extends State<YellowBird> {
  bool animate = true;

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: AlignmentDirectional.topCenter,
      children: [
      Positioned(
        bottom: 0,
        child: AnimatedContainer(
            width: 54.0,
            decoration: BoxDecoration(
             color: Colors.redAccent,
             borderRadius: BorderRadius.all(Radius.circular(360))
            ),
            height: animate ? 56.0 : 250.0,
            duration: Duration(milliseconds: 300),
            child: animate
                ? Container()
                : Column(
                    children: List.generate(
                        4,
                        (i) => Expanded(
                                child: Container(
                              width: 50,
                              height: 50,
                              decoration: BoxDecoration(
                                color: Colors.white,
                                shape: BoxShape.circle,
                              ),
                           ),
                        ),
                     ),
                  ),
               ),
            ),
      Positioned(
          bottom: 0,
          child: FloatingActionButton(
              backgroundColor: Colors.grey,
          child: Icon(animate ? Icons.menu : Icons.close, size: 30),
              onPressed: () {
                setState(() {
                  animate = !animate;
                });
              })),
    ]);
  }
}

cho tôi biết nếu điều này hoạt động hoặc họ có bất cứ điều gì để thay đổi từ điều này.

mohandesR Nov 03 2020 at 03:24

xin chào, hãy xem thư viện này ... https://pub.dev/packages/flutter_portal đây là cách đơn giản nhất để tạo lớp phủ trong Flutter ...

PortalEntry(
  visible: isMenuVisible, //true Or False
  portalAnchor: Alignment.topLeft,
  childAnchor: Alignment.topRight,
  portal: TheMenuWidget, // option 1 + option 2 (White)
  child: MyButton, // show Menu Button (Grey) 
)