提記:
愛情
一段感情能給你帶來多少痛苦怎憋,就曾給你帶來過多大快樂
既想放棄,又想糾纏乒疏,內(nèi)心經(jīng)歷了多少痛苦和掙扎
用一轉(zhuǎn)身離開嗡呼,用一輩子忘記
需求背景:
那天,產(chǎn)品經(jīng)理說“我在微信朋友圈里點了別人分享出來的歌曲鏈接 聽了會歌 那歌簡直了 好聽 退到聊天界面 出現(xiàn)了個懸浮的歌曲圖標(biāo) 那我們能不能做類似的 在所有頁面都會存在這樣一個懸浮圖標(biāo) 這個圖標(biāo)目前要有打客服電話功能”占卧。
我一心想,這人真會搞事 哈哈。行 滿足他
OverlayState是什么铆铆?
事實上有一個Overlay的widget,它的createState方法獲取的就是OverlayState對象.
Overlay可以認為是一個UI上面的蒙版/浮空層,使用起來類似Stack;
有這幾個API 熟悉一下
OverlayState.insert(OverlayEntry) //添加
OverlayEntry.remove() //移除
在pubspec.yaml添加url_launcher依賴
dependencies:
flutter:
sdk: flutter
url_launcher: ^5.5.0
先定義個Application類
import 'package:flutter/cupertino.dart';
class Application {
///應(yīng)用全局 ke
static GlobalKey<NavigatorState> globalKey;
static OverlayEntry overlayEntry;
}
主入口程序如下
void main() {
GlobalKey<NavigatorState> globalKey = new GlobalKey<NavigatorState>();
Application.globalKey = globalKey;
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
///注意 一定要navigatorKey 才能在所有界面上顯示
navigatorKey: Application.globalKey,
home: MyHomePage(),
);
}
}
MyHomePage類
class MyHomePage extends StatefulWidget {
@override
_SecondState createState() => _SecondState();
}
class _MyHomePageState extends State<Second> {
OverlayEntry overlayEntry;
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
///WidgetsBinding.instance.addPostFrameCallback 這個作用是界面繪制完成的監(jiān)聽回調(diào) 必須在繪制完成后添加OverlayEntry
///MediaQuery.of(context).size.width 屏幕寬度
///MediaQuery.of(context).size.height 屏幕高度
addOverlayEntry(MediaQuery.of(context).size.width - 80, MediaQuery.of(context).size.height - 80);
});
}
Future addOverlayEntry(double left, double top) async {
Application.overlayEntry?.remove();
overlayEntry = OverlayEntry(
builder: (BuildContext context) => Positioned(
top: top,
left: left,
child: GestureDetector(
onTap: () async{
///在這里實現(xiàn)撥打客服電話功能
const url = 'tel:17601290637';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
},
child: Draggable(
onDragEnd: (DraggableDetails details) {
///拖動結(jié)束
addOverlayEntry(details.offset.dx, details.offset.dy);
},
///feedback是拖動時跟隨手指滑動的Widget窝撵。
feedback: Icon(Icons.add_call, color: Colors.red,),
///child是靜止時顯示的Widget傀顾,
child: Icon(Icons.add_call, color: Colors.red,))
),
)
);
/// 賦值 方便移除
Application.overlayEntry = overlayEntry;
Application.globalKey.currentState.overlay.insert(overlayEntry);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}