Skip to content

Commit

Permalink
新增页面悬浮托动按钮
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaolongs committed Mar 6, 2022
1 parent 77f630e commit 4230972
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@

## [3.0.3] 新增页面悬浮托动按钮
## [3.0.2] 文档更新

## [3.0.1] RoteFloatingButton 支持设置按钮大小
Expand Down
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,45 @@ Flutter抖动动画组件,FLutter颤动动画
},
)
```

#### 6 页面悬浮可托动按钮

![](images/float_fab_button.gif)
```
class _Exam223HomePageState extends State<Exam223HomePage> {
//Stack使用的Key
final GlobalKey _parentKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Stack(
key: _parentKey,
children: [
Container(color: Colors.blueGrey),
DraggableFloatingActionButton(
child: Container(
width: 60,
height: 60,
decoration: const ShapeDecoration(
shape: CircleBorder(),
color: Colors.white,
),
child: const Icon(Icons.add),
),
initialOffset: const Offset(120, 70),
parentKey: _parentKey,
onPressed: () {},
),
],
),
),
);
}
}
```
62 changes: 61 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,18 @@ class _Exam220HomePageState extends State<Exam222HomePage> {
return Example309();
}));
},
child: Text("开源中图底部菜单"))
child: Text("开源中图底部菜单")),

ElevatedButton(
onPressed: () {
Navigator.of(context).push(new MaterialPageRoute(
builder: (BuildContext context) {
return Exam223HomePage();
}));
},
child: Text("可托动的悬浮按钮")),


],
),
//向上弹出的按钮组件
Expand Down Expand Up @@ -242,3 +253,52 @@ class _ExampleState extends State<Example309> {
);
}
}





class Exam223HomePage extends StatefulWidget {
const Exam223HomePage({Key? key}) : super(key: key);

@override
State<Exam223HomePage> createState() => _Exam223HomePageState();
}

///代码清单2-27 可托动的悬浮按钮
class _Exam223HomePageState extends State<Exam223HomePage> {
//Stack使用的Key
final GlobalKey _parentKey = GlobalKey();

@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
width: double.infinity,
height: double.infinity,
child: Stack(
key: _parentKey,
children: [
Container(color: Colors.blueGrey),

DraggableFloatingActionButton(
child: Container(
width: 60,
height: 60,
decoration: const ShapeDecoration(
shape: CircleBorder(),
color: Colors.white,
),
child: const Icon(Icons.add),
),
initialOffset: const Offset(120, 70),
parentKey: _parentKey,
onPressed: () {},
),
],
),
),
);
}
}
Binary file added images/float_fab_button.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion lib/shake_animation_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ export 'package:shake_animation_widget/src/rote_floating_button.dart';
export 'package:shake_animation_widget/src/animated_button.dart';
export 'package:shake_animation_widget/src/animated_button_statue.dart';
export 'package:shake_animation_widget/src/bottom_round_flow_menu.dart';
export 'package:shake_animation_widget/src/rote_flow_button_menu.dart';
export 'package:shake_animation_widget/src/rote_flow_button_menu.dart';
export 'package:shake_animation_widget/src/draggable_floating_action_button.dart';
113 changes: 113 additions & 0 deletions lib/src/draggable_floating_action_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

//静态路由配置///代码清单2-27-1 可托动的悬浮按钮
///代码路径 lib/code2/draggable_floating_action_button.dart
class DraggableFloatingActionButton extends StatefulWidget {
final Widget child;
final Offset initialOffset;
final VoidCallback onPressed;
GlobalKey<State<StatefulWidget>> parentKey;
DraggableFloatingActionButton({
required this.child,
required this.initialOffset,
required this.onPressed,
required this.parentKey,
});

@override
State<StatefulWidget> createState() => _DraggableFloatingActionButtonState();
}

class _DraggableFloatingActionButtonState
extends State<DraggableFloatingActionButton> {
//托动按钮使用的Key
final GlobalKey _key = GlobalKey();
bool _isDragging = false;
late Offset _offset;
late Offset _minOffset;
late Offset _maxOffset;

@override
void initState() {
super.initState();
//托动按钮的初始位置
_offset = widget.initialOffset;
//添加视图监听
WidgetsBinding.instance?.addPostFrameCallback(_initBoundary);
}
//页面第一帧绘制完成后调用
void _initBoundary(_) {
//获取获取组件的 RenderBox
final RenderBox parentRenderBox =
widget.parentKey.currentContext?.findRenderObject() as RenderBox;
//获取托动按钮组件的 RenderBox
final RenderBox renderBox =
_key.currentContext?.findRenderObject() as RenderBox;

try {
//分别获取两者的大小 从而计算边界
final Size parentSize = parentRenderBox.size;
final Size size = renderBox.size;
setState(() {
_minOffset = const Offset(0, 0);
_maxOffset = Offset(
parentSize.width - size.width, parentSize.height - size.height);
});
} catch (e) {
print('catch: $e');
}
}
///代码清单2-27-3 计算按钮位置
void _updatePosition(PointerMoveEvent pointerMoveEvent) {
double newOffsetX = _offset.dx + pointerMoveEvent.delta.dx;
double newOffsetY = _offset.dy + pointerMoveEvent.delta.dy;

if (newOffsetX < _minOffset.dx) {
newOffsetX = _minOffset.dx;
} else if (newOffsetX > _maxOffset.dx) {
newOffsetX = _maxOffset.dx;
}

if (newOffsetY < _minOffset.dy) {
newOffsetY = _minOffset.dy;
} else if (newOffsetY > _maxOffset.dy) {
newOffsetY = _maxOffset.dy;
}

setState(() {
_offset = Offset(newOffsetX, newOffsetY);
});
}
///代码清单2-27-2 可托动的悬浮按钮
@override
Widget build(BuildContext context) {
return Positioned(
left: _offset.dx,
top: _offset.dy,
child: Listener(
onPointerMove: (PointerMoveEvent pointerMoveEvent) {
//更新位置
_updatePosition(pointerMoveEvent);
setState(() {
_isDragging = true;
});
},
onPointerUp: (PointerUpEvent pointerUpEvent) {
print('onPointerUp');
if (_isDragging) {
setState(() {
_isDragging = false;
});
} else {
widget.onPressed();
}
},
child: Container(
key: _key,
child: widget.child,
),
),
);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: shake_animation_widget
description: 抖动动画、向上弹出动画、抖动文本、垂直圆形菜单、底部圆形菜单、动画进度按钮
version: 3.0.2
version: 3.0.3
homepage: https://github.com/zhaolongs/flutter_shake_animation_widget.git

environment:
Expand Down

0 comments on commit 4230972

Please sign in to comment.