颤动实现应用内小窗
作者:访客发布时间:2023-12-15分类:程序开发学习浏览:99
导读:前言Ffltter是一种强大的跨平台移动应用开发框架,允许开发者构建美观且高性能的移动应用。在某些情况下,你可能需要在应用内实现小窗口功能,以改善用户体验或提供一些特定的功能.无论...
前言
Ffltter是一种强大的跨平台移动应用开发框架,允许开发者构建美观且高性能的移动应用。在某些情况下,你可能需要在应用内实现小窗口功能,以改善用户体验或提供一些特定的功能.无论是用于显示通知、音乐播放器控制、或其他创意功能,应用内小窗口都是提高用户体验的有力工具.
本文将介绍如何在Ffltter应用内创建小窗口,并展示一个简单的示例。
一般我们对小窗有如下要求:
- 跨页面显示
- 可以跟随手指拖动
- 放开自动侧边吸附
代码实现
完整代码
小窗的显示与隐藏
使用OverlayEntry
进行跨页面显示
首先定义一个窗口管理器,进行窗口的显示和隐藏
class SmallWindowManager {
static final SmallWindowManager _instance = SmallWindowManager._();
factory SmallWindowManager() => _instance;
SmallWindowManager._();
///浮窗
OverlayEntry? overlayEntry;
show(BuildContext context) {
if (overlayEntry == null) {
overlayEntry = OverlayEntry(builder: (BuildContext context) {
return SmallWindowWidget(
top: 160,
left: 279,
child: GestureDetector(
onTap: () {
hide();
},
child: Material(
child: Container(
color: Colors.red,
width: 100,
height: 200,
child: const Center(
child: Text("small"),
),
),
),
),
);
});
Overlay.of(context).insert(overlayEntry!);
}
}
///关闭小窗
void hide() {
overlayEntry?.remove();
overlayEntry = null;
}
}
小窗跟随与吸附
- 使用
Positioned
的left
和top
属性进行定位,通过key
确定小窗和窗口的尺寸,判定小窗移动的边界 - 使用
Gestedrector
进行手势操作,手指移动时回调onPanUpdate
,通过手指的偏移量计算定位,小窗即可跟随手指移动 - 松开手指时回调
onPanEnd
,计算开始位置和结束位置,执行吸附动画
class SmallWindowWidget extends StatefulWidget {
final Duration duration;
final Widget child;
final double top;
final double left;
const SmallWindowWidget({
super.key,
this.duration = const Duration(milliseconds: 100),
required this.child,
required this.top,
required this.left,
});
@override
State<SmallWindowWidget> createState() => _SmallWindowWidgetState();
}
class _SmallWindowWidgetState extends State<SmallWindowWidget> with TickerProviderStateMixin {
AnimationController? _controller;
double left = 0;
double top = 0;
double maxX = 0;
double maxY = 0;
var parentKey = GlobalKey();
var childKey = GlobalKey();
var parentSize = const Size(0, 0);
var childSize = const Size(0, 0);
@override
void initState() {
left = widget.left;
top = widget.top;
WidgetsBinding.instance.addPostFrameCallback((d) {
parentSize = getWidgetSize(parentKey);
childSize = getWidgetSize(childKey);
maxX = parentSize.width - childSize.width;
maxY = parentSize.height - childSize.height;
});
super.initState();
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
key: parentKey,
fit: StackFit.expand,
children: [
Positioned(
key: childKey,
left: left,
top: top,
child: GestureDetector(
onPanUpdate: (d) {
var delta = d.delta;
left += delta.dx;
top += delta.dy;
setState(() {});
},
onPanEnd: (d) {
left = getValue(left, maxX);
top = getValue(top, maxY);
adsorb();
},
child: widget.child,
),
)
],
);
}
///限制边界
double getValue(double value, double max) {
if (value < 0) {
return 0;
} else if (value > max) {
return max;
} else {
return value;
}
}
///吸附
void adsorb() {
bool isLeft = (left + childSize.width / 2) < parentSize.width / 2;
_controller = AnimationController(vsync: this)..duration = widget.duration;
var animation = Tween<double>(begin: left, end: isLeft ? 0 : maxX).animate(_controller!);
animation.addListener(() {
left = animation.value;
setState(() {});
});
_controller!.forward();
}
Size getWidgetSize(GlobalKey key) {
final RenderBox renderBox = key.currentContext?.findRenderObject() as RenderBox;
return renderBox.size;
}
}
- 程序开发学习排行
-
- 1鸿蒙HarmonyOS:Web组件网页白屏检测
- 2HTTPS协议是安全传输,为啥还要再加密?
- 3HarmonyOS鸿蒙应用开发——数据持久化Preferences
- 4记解决MaterialButton背景颜色与设置值不同
- 5鸿蒙HarmonyOS实战-ArkUI组件(RelativeContainer)
- 6鸿蒙HarmonyOS实战-ArkUI组件(Stack)
- 7[Android][NDK][Cmake]一文搞懂Android项目中的Cmake
- 8Android广播如何解决Sending non-protected broadcast问题
- 9鸿蒙HarmonyOS实战-ArkUI组件(mediaquery)
- 最近发表
-
- WooCommerce最好的WordPress常用插件下载博客插件模块的相关产品
- 羊驼机器人最好的WordPress常用插件下载博客插件模块
- IP信息记录器最好的WordPress常用插件下载博客插件模块
- Linkly for WooCommerce最好的WordPress常用插件下载博客插件模块
- 元素聚合器Forms最好的WordPress常用插件下载博客插件模块
- Promaker Chat 最好的WordPress通用插件下载 博客插件模块
- 自动更新发布日期最好的WordPress常用插件下载博客插件模块
- WordPress官方最好的获取回复WordPress常用插件下载博客插件模块
- Img to rss最好的wordpress常用插件下载博客插件模块
- WPMozo为Elementor最好的WordPress常用插件下载博客插件模块添加精简版