WDScreenButton:打造自定義可拖動(dòng)懸浮按鈕
在移動(dòng)應(yīng)用開發(fā)中,懸浮按鈕是一種常見的交互元素,它可以提供快速便捷的操作入口。然而,Flutter框架并未提供直接支持懸浮按鈕拖動(dòng)功能的組件。為了解決這一問題,我開發(fā)了WDScreenButton,它能夠輕松實(shí)現(xiàn)自定義可拖動(dòng)的懸浮按鈕,并且提供了豐富的定制化選項(xiàng)。(用gpt又寫了一篇)
1. 靈活的定制化
WDScreenButton允許開發(fā)者根據(jù)自身應(yīng)用的需求進(jìn)行靈活定制,包括按鈕位置、初始顯示狀態(tài)、按鈕樣式等。通過簡單的配置,開發(fā)者可以輕松創(chuàng)建出符合應(yīng)用設(shè)計(jì)風(fēng)格的懸浮按鈕,提升用戶體驗(yàn)和應(yīng)用整體美感。
2. 拖動(dòng)交互支持
WDScreenButton支持拖動(dòng)交互,用戶可以通過觸摸拖動(dòng)按鈕的方式調(diào)整按鈕位置,從而更好地適配不同屏幕尺寸和用戶習(xí)慣。這種直觀的交互方式不僅增加了用戶與應(yīng)用的互動(dòng)性,同時(shí)也提升了用戶對(duì)應(yīng)用功能的操作效率。
3. 完整代碼
import 'package:flutter/material.dart';
typedef WDScreenButtonCallBack = void Function();
class WDScreenButton {
static OverlayEntry? _overlayEntry;
///是否顯示
static bool isShow = false;
static WDScreenButtonCallBack? _callBack;
static GlobalKey<NavigatorState>? _globalKey;
static double _dx = 30;
static double _dy = 100;
static Widget? _buttonChild;
///是否初始化
static bool isInit = false;
///顯示/隱藏按鈕
static changeStatus(bool status){
isShow = status;
Future.delayed(Duration(milliseconds: 330)).then((value) {
_overlayEntry?.markNeedsBuild();
});
}
static initConfig(GlobalKey<NavigatorState> globalKey,{double left = 30, double top = 100,
bool isShowBtn = false,Widget? buttonChild,WDScreenButtonCallBack? callBack}){
if(isInit){
return;
}
isShow = isShowBtn;
_callBack = callBack;
_dx = left;
_dy = top;
_buttonChild = buttonChild;
_globalKey = globalKey;
WidgetsBinding.instance.addPostFrameCallback((_) {
_init();
});
}
///初始化
static _init() {
_overlayEntry?.remove();
_overlayEntry = null;
_overlayEntry = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: _dy,
left: _dx,
child: GestureDetector(
onTap: () {
if (_callBack != null) {
_callBack!();
}
},
child: Offstage(
offstage: !isShow,
child: Draggable(
onDragUpdate: (DragUpdateDetails details){
},
onDragEnd: (DraggableDetails details) {
///拖動(dòng)結(jié)束
_dx = details.offset.dx;
_dy = details.offset.dy;
if (_dx < 30) {
_dx = 30;
} else if (_dx > MediaQuery.of(context).size.width - 30) {
_dx = MediaQuery.of(context).size.width-30;
}
if (_dy < 100) {
_dy = 100;
}else if (_dy > MediaQuery.of(context).size.height - 100) {
_dy = MediaQuery.of(context).size.height - 100;
}
_overlayEntry?.markNeedsBuild();
},
childWhenDragging: SizedBox.shrink(),
feedback: _buttonChild ?? Icon(Icons.pest_control_sharp,size: 40,color: Colors.blueAccent,),
child:_buttonChild ?? Icon(Icons.pest_control_sharp,size: 40,color: Colors.blueAccent)),
)
),
)
);
if (_globalKey?.currentState?.overlay != null) {
_globalKey!.currentState!.overlay!.insert(_overlayEntry!);
isInit = true;
}
}
}
4. 如何使用WDScreenButton
- 在需要使用的頁面引入WDScreenButton:
import 'xxxx/wd_screen_button.dart';
- 在頁面初始化階段進(jìn)行配置:
WDScreenButton.initConfig(
globalKey,
left: 30,
top: 100,
isShowBtn: true,
buttonChild: Icon(Icons.add, size: 36, color: Colors.white),
callBack: () {
// 點(diǎn)擊按鈕觸發(fā)的操作
},
);
5. 結(jié)語
WDScreenButton為Flutter開發(fā)者提供了一種簡單、靈活的方式來創(chuàng)建自定義可拖動(dòng)懸浮按鈕,為應(yīng)用增添了更多的交互元素和個(gè)性化定制空間。我相信,WDScreenButton將成為您開發(fā)暢、具有吸引力的應(yīng)用界面的得力助手。