Flutter-滑动或按下floatActionButton来展开bottomNavigationBar [英] Flutter - Expand bottomNavigationBar by swiping or pressing the floatingActionButton

查看:249
本文介绍了Flutter-滑动或按下floatActionButton来展开bottomNavigationBar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 DashboardWidget 的主窗口小部件。在其中,我有一个 Scaffold 和一个 BottomNavigationBar 和一个 FloatingActionButton





现在,我要会通过以下方式从底部拖动的小部件:


  1. 用手指轻扫。

  2. 按下 FloatingActionButton

换句话说,我想扩展 BottomNavigationBar








我使用了另一种方法,并且没有 AnimationController GlobalKey 等,逻辑代码非常短( _handleClick )。



我只使用了4个变量,简单而又简短!

  void main()=> runApp(MaterialApp(home:HomePage())); 

类HomePage扩展了StatefulWidget {
@override
_HomePageState createState()=> _HomePageState();
}

类_HomePageState扩展了State< HomePage> {
静态double _minHeight = 80,_maxHeight = 600;
偏移量_offset =偏移量(0,_minHeight);
bool _isOpen = false;

@override
小部件构建(BuildContext上下文){
return Scaffold(
backgroundColor:Color(0xFFF6F6F6),
appBar:AppBar(backgroundColor:Color (0xFFF6F6F6),海拔高度:0),
主体:堆栈(
对齐方式:Alignment.bottomCenter,
子对象:< Widget> [
Align(
对齐方式: Alignment.topLeft,
子对象:FlatButton(
onPressed:_handleClick,
splashColor:Colors.transparent,
textColor:Colors.grey,
子对象:Text(_isOpen? Back:),
),
),
Align(child:FlutterLogo(size:300)),
GestureDetector(
onPanUpdate:(详细信息){
_offset =偏移量(0,_offset.dy-details.delta.dy);
if(_offset.dy&_HomePageState._minHeight){
_offset =偏移量(0,_HomePageState ._minHeight);
_isOpen = false;
}否则,如果(_offset.dy> _HomePageState._maxHeight){
_offset =偏移量(0,_HomePageState._maxHeight);
_isOpen = true;
}
setState((){});
},
子级:AnimatedContainer(
持续时间:Duration.zero,
曲线:Curves.easeOut,
高度:_offset.dy,
对齐方式: Alignment.center,
装饰:BoxDecoration(
颜色:Colors.white,
borderRadius:BorderRadius.only(
top左:Radius.circular(30),
topRight :Radius.circular(30),
),
boxShadow:[BoxShadow(color:Colors.grey.withOpacity(0.5),spreadRadius:5,blurRadius:10)]),
子级:Text( This is my Bottom sheet),
),
),
Positioned(
bottom:2 * _HomePageState._minHeight-_offset.dy-28,// 56是FAB的高度,所以我们在这里使用它的一半。
子级:FloatingActionButton(
子级:Icon(_isOpen?Icons.keyboard_arrow_dow n:Icons.add),
onPressed:_handleClick,
),
),
],
),
);
}

//首先,它打开工作表,再次调用时,它关闭。
void _handleClick(){
_isOpen =!_isOpen;
Timer.periodic(Duration(milliseconds:5),(timer){
if(_isOpen){
double value = _offset.dy + 10; //我们增加容器的高度每5ms乘10
_offset = Offset(0,value);
if(_offset.dy> _maxHeight){
_offset = Offset(0,_maxHeight); //确保它确实不能超过maxHeight
timer.cancel();
}
}否则{
double value = _offset.dy-10; //我们在此处将高度减10 b $ b _offset =偏移量(0,值);
if(_offset.dy&_minHeight){
_offset =偏移量(0,_minHeight); //确保其不超过minHeight
timer.cancel();
}
}
setState((){});
});
}
}


I have a main widget called DashboardWidget. Inside it, I have a Scaffold with BottomNavigationBar and a FloatingActionButton:

Now, I want to make a widget that would be dragged from the bottom by:

  1. Swiping up with the finger.
  2. Pressing on FloatingActionButton.

In other words, I want to expand the BottomNavigationBar.

Here's a design concept in case I was unclear.

The problem is, I'm not sure where to start to implement that. I've thought about removing the BottomNavigationBar and create a custom widget that can be expanded, but I'm not sure if it's possible either.

解决方案

Output:


I used a different approach and did it without AnimationController, GlobalKey etc, the logic code is very short (_handleClick).

I only used 4 variables, simple and short!

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(() {});
    });
  }
}

这篇关于Flutter-滑动或按下floatActionButton来展开bottomNavigationBar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆