如何用颤振制作顶部导航抽屉?
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 做了类似的事情,它是 DialogBuilder 的父级,带有动画参数,你也可以设置暗淡的颜色等。 比如说,在主小部件中有一个按钮:
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,
),
],
);
【讨论】:
以上是关于如何用颤振制作顶部导航抽屉?的主要内容,如果未能解决你的问题,请参考以下文章