我有一个名为的主窗口小部件DashboardWidget。在里面,我有一个ScaffoldwithBottomNavigationBar和一个FloatingActionButton:
DashboardWidget
Scaffold
BottomNavigationBar
FloatingActionButton
现在,我想制作一个可通过以下方式从底部拖动的小部件:
换句话说,我想扩展BottomNavigationBar。
如果我不清楚,这是一个设计概念。
问题是,我不确定从哪里开始实施。我已经考虑过删除BottomNavigationBar并创建一个可以扩展的自定义窗口小部件,但是我不确定是否也可以。
输出:
我使用了另一种方法,并且没有使用AnimationController,GlobalKey等等,逻辑代码非常短(_handleClick)。
AnimationController
GlobalKey
_handleClick
我只使用了4个变量,简单而又简短!
void main() => runApp(MaterialApp(home: HomePage())); class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { static double _minHeight = 80, _maxHeight = 600; Offset _offset = Offset(0, _minHeight); bool _isOpen = false; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFFF6F6F6), appBar: AppBar(backgroundColor: Color(0xFFF6F6F6), elevation: 0), body: Stack( alignment: Alignment.bottomCenter, children: <Widget>[ Align( alignment: Alignment.topLeft, child: FlatButton( onPressed: _handleClick, splashColor: Colors.transparent, textColor: Colors.grey, child: Text(_isOpen ? "Back" : ""), ), ), Align(child: FlutterLogo(size: 300)), GestureDetector( onPanUpdate: (details) { _offset = Offset(0, _offset.dy - details.delta.dy); if (_offset.dy < _HomePageState._minHeight) { _offset = Offset(0, _HomePageState._minHeight); _isOpen = false; } else if (_offset.dy > _HomePageState._maxHeight) { _offset = Offset(0, _HomePageState._maxHeight); _isOpen = true; } setState(() {}); }, child: AnimatedContainer( duration: Duration.zero, curve: Curves.easeOut, height: _offset.dy, alignment: Alignment.center, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30), ), boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.5), spreadRadius: 5, blurRadius: 10)]), child: Text("This is my Bottom sheet"), ), ), Positioned( bottom: 2 * _HomePageState._minHeight - _offset.dy - 28, // 56 is the height of FAB so we use here half of it. child: FloatingActionButton( child: Icon(_isOpen ? Icons.keyboard_arrow_down : Icons.add), onPressed: _handleClick, ), ), ], ), ); } // first it opens the sheet and when called again it closes. void _handleClick() { _isOpen = !_isOpen; Timer.periodic(Duration(milliseconds: 5), (timer) { if (_isOpen) { double value = _offset.dy + 10; // we increment the height of the Container by 10 every 5ms _offset = Offset(0, value); if (_offset.dy > _maxHeight) { _offset = Offset(0, _maxHeight); // makes sure it does't go above maxHeight timer.cancel(); } } else { double value = _offset.dy - 10; // we decrement the height by 10 here _offset = Offset(0, value); if (_offset.dy < _minHeight) { _offset = Offset(0, _minHeight); // makes sure it doesn't go beyond minHeight timer.cancel(); } } setState(() {}); }); } }