144 lines
3.7 KiB
Dart
144 lines
3.7 KiB
Dart
/// 可拖拽广告红包组件
|
|
library;
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
class Ads extends StatefulWidget {
|
|
const Ads({super.key});
|
|
|
|
@override
|
|
State<Ads> createState() => _AdsState();
|
|
}
|
|
|
|
class _AdsState extends State<Ads> with WidgetsBindingObserver {
|
|
double winWidth = 0.0;
|
|
double winHeight = 0.0;
|
|
double dx = 10.0;
|
|
double dy = 120.0;
|
|
double ballWidth = 50.0;
|
|
double ballHeight = 50.0;
|
|
bool isAnimate = false;
|
|
// 是否显示
|
|
bool isVisible = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addObserver(this);
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
updateResize();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
WidgetsBinding.instance.removeObserver(this);
|
|
super.dispose();
|
|
}
|
|
|
|
// 监听窗口尺寸变化
|
|
@override
|
|
void didChangeMetrics() {
|
|
super.didChangeMetrics();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
updateResize();
|
|
});
|
|
}
|
|
|
|
// 更新设备尺寸
|
|
void updateResize() {
|
|
setState(() {
|
|
winWidth = MediaQuery.of(context).size.width;
|
|
winHeight = MediaQuery.of(context).size.height;
|
|
});
|
|
}
|
|
|
|
// 拖拽更新
|
|
void onPanUpdate(Offset position) {
|
|
isAnimate = false;
|
|
dx = position.dx - ballWidth / 2;
|
|
dy = position.dy - ballHeight / 2;
|
|
setState(() {});
|
|
}
|
|
|
|
// 拖拽结束
|
|
void onPanEnd(Offset position) {
|
|
isAnimate = true;
|
|
if (dx + ballWidth / 2 < winWidth / 2) {
|
|
dx = 10.0;
|
|
} else {
|
|
dx = winWidth - ballWidth - 10.0;
|
|
}
|
|
if (dy + ballHeight > winHeight / 2) {
|
|
dy = winHeight / 2 - ballHeight;
|
|
} else if (dy < 120) {
|
|
dy = 120.0;
|
|
}
|
|
setState(() {});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Visibility(
|
|
visible: isVisible,
|
|
child: AnimatedPositioned(
|
|
duration: Duration(milliseconds: isAnimate ? 200 : 0),
|
|
left: dx,
|
|
top: dy,
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onPanUpdate: (DragUpdateDetails details) {
|
|
onPanUpdate(details.globalPosition);
|
|
},
|
|
onPanEnd: (details) {
|
|
onPanEnd(details.globalPosition);
|
|
},
|
|
onTap: () {
|
|
debugPrint('click ads');
|
|
},
|
|
child: Stack(
|
|
children: [
|
|
SizedBox(
|
|
height: ballHeight,
|
|
width: ballWidth,
|
|
child: UnconstrainedBox(
|
|
child: Container(
|
|
height: 40.0,
|
|
width: 40.0,
|
|
decoration: BoxDecoration(
|
|
color: Colors.black.withAlpha(50),
|
|
borderRadius: BorderRadius.circular(100.0),
|
|
),
|
|
child: UnconstrainedBox(
|
|
child: Image.asset(
|
|
'assets/images/hbico.png',
|
|
width: 25.0,
|
|
fit: BoxFit.contain,
|
|
),
|
|
),
|
|
),
|
|
)),
|
|
Positioned(
|
|
right: 0,
|
|
top: 0,
|
|
child: GestureDetector(
|
|
child: Icon(
|
|
Icons.close,
|
|
color: Colors.white,
|
|
size: 10.0,
|
|
),
|
|
onTap: () {
|
|
setState(() {
|
|
isVisible = false;
|
|
});
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|