问题描述
我有一个名为 DashboardWidget
的主窗口小部件。在其中,我有一个 Scaffold
和一个 BottomNavigationBar
和一个 FloatingActionButton
:
现在,我要会通过以下方式从底部拖动的小部件:
- 用手指轻扫。
- 按下
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:
- Swiping up with the finger.
- 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!