如何用颤振制作顶部导航抽屉?

Posted

技术标签:

【中文标题】如何用颤振制作顶部导航抽屉?【英文标题】:How to make top navigation drawer with flutter? 【发布时间】:2020-04-15 07:08:46 【问题描述】:

我正在尝试在 appBar 按钮 click 上打开一个导航抽屉,如底部工作表。 我浏览了它,但找不到任何解决方案。

见下图:

我正在尝试的代码:

 return Scaffold(
      backgroundColor: Colors.transparent,
      body: Container(
        height: MediaQuery.of(context).size.height/2,
        //constraints: BoxConstraints.expand(),
        decoration: BoxDecoration(
          color: Color.fromARGB(255, 255, 255, 255),
        ),
      )
    );

但背景为黑色,无法看到上一页的部分视图。

【问题讨论】:

【参考方案1】:

您可以看到一个示例小部件BackDrop

我想如果你改变顶部和底部的位置,一切都会完美的

Animation<RelativeRect> _getPanelAnimation(BoxConstraints constraints) 
  final double height = constraints.biggest.height;
  final double top = height - _PANEL_HEADER_HEIGHT;
  final double bottom = -_PANEL_HEADER_HEIGHT;
  return new RelativeRectTween(
    begin: new RelativeRect.fromLTRB(0.0, top, 0.0, bottom),
    end: new RelativeRect.fromLTRB(0.0, 0.0, 0.0, 0.0),
  ).animate(new CurvedAnimation(parent: _controller, curve: Curves.linear));

【讨论】:

【参考方案2】:

最后我用 SlideTransition() Widget 添加了动画。因为我没有得到任何完美的解决方案,但它运行完美,我很满意 :)。


 new IconButton(
    icon: new Image.asset('assets/images/ui-16px-3-funnel-40.png'),
    onPressed: ()         
     showDialog(
      context: context,
      child: FiltersPage()
     );
   ,
 ),





import 'package:flutter/material.dart';

class FiltersPage extends StatefulWidget 
  @override
  _FiltersPageState createState() => _FiltersPageState();


class _FiltersPageState extends State<FiltersPage> with SingleTickerProviderStateMixin

  AnimationController controller;
  Animation<Offset> slideAnimation;

  @override
  void initState() 
    controller =  AnimationController(vsync: this, duration: Duration(milliseconds: 450)); 
    slideAnimation = Tween<Offset>(begin: Offset(0.0, -4.0), end: Offset.zero)
      .animate(CurvedAnimation(parent: controller, curve: Curves.decelerate));
    controller.addListener(() 
      setState(() );
    );
    controller.forward();
    super.initState();
  

  @override
  Widget build(BuildContext context) 
    return SlideTransition(
      position: slideAnimation,
      child: Scaffold(
        backgroundColor: Colors.transparent,
        appBar:AppBar(.......)
        body: Container(
        padding: const EdgeInsets.all(13.0),
          height: MediaQuery.of(context).size.height/2.7,
          width: MediaQuery.of(context).size.width,
          decoration: BoxDecoration(
            color: Color.fromARGB(255, 255, 255, 255),
          ),
         child:Column(.....)
       )
    );
  


【讨论】:

【参考方案3】:

flutter中有一个小部件BackDrop可以做你想要的功能。你需要使用backdrop 0.2.7库。你可以参考Flutter Backdrop

【讨论】:

【参考方案4】:

我使用 PageRouteBuilder 做了类似的事情,它是 DialogBu​​ilder 的父级,带有动画参数,你也可以设置暗淡的颜色等。 比如说,在主小部件中有一个按钮:

TextButton(
        child: Text("open drawer"),
        onPressed: () 
          Navigator.of(context).push(_createRoute());
        ,
      )

然后是带有动画等的路线构建器:

  Route _createRoute() 
    return PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) => TopDrawer(),
      transitionsBuilder: (context, animation, secondaryAnimation, child) 
        const begin = Offset(0.0, -4.0);
        const end = Offset.zero;
        const curve = Curves.decelerate;
        var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));

        return SlideTransition(
          position: tween.animate(animation),
          child: child,
        );
      ,
      opaque: false,
      barrierDismissible: true,
      barrierColor: Color.fromRGBO(100, 100, 100, 0.5), //color of the grayed under
      transitionDuration: Duration(milliseconds: 450),
      reverseTransitionDuration: Duration(milliseconds: 450),
    );
  

它显示的抽屉页面:

import 'package:flutter/material.dart';

class TopDrawer extends StatelessWidget 
  const TopDrawer(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    return Column(
      children: [
        Container(
          height: MediaQuery.of(context).size.height/2,
          width: MediaQuery.of(context).size.width,
          child: Text("some content here"),
          color: Colors.green,
        ),
      ],
    );
  

【讨论】:

以上是关于如何用颤振制作顶部导航抽屉?的主要内容,如果未能解决你的问题,请参考以下文章

在颤振中,如何移动导航抽屉的内容而不是覆盖在顶部。

如何用颤振制作一个mysql实时数据库? [关闭]

如何用Bootstrap制作导航条

如何使用同一个应用制作抽屉式导航和底部导航?

如何在导航抽屉中制作另一个项目?

Android Studio 导航抽屉,如 Gmail 应用