2. sensors_plus(Null safety)
(1)描述:判断设备状态的速度和重力感应
(2)适合平台:ANDRIOD、IOS、WEB
(3)补充:主要说明:AccelerometerEvent
AccelerometerEvent
:描述设备的速度,包括重力的影响。可用于判断设备是否向特定方向移动UserAccelerometerEvent
:描述设备的速度,但不包括重力。它通常被认为是用户对设备的影响GyroscopeEvent
:描述设备的旋转
(4)使用
import 'package:sensors_plus/sensors_plus.dart'; accelerometerEvents.listen((AccelerometerEvent event) { print(event); }); // [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)] userAccelerometerEvents.listen((UserAccelerometerEvent event) { print(event); }); // [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)] gyroscopeEvents.listen((GyroscopeEvent event) { print(event); }); // [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)]
(5)实现逻辑
:首先利用全局key获取紫色边框(容器)的坐标,然后根据重力感应不断修改加号图标的位置。
AccelerometerEvent? acceleration; late Timer _timer; /// 容器的key GlobalKey containerKey = GlobalKey(); /// 容器的xy界限 late RenderBox containerRenderBox; var containerOffset; var containerLeftX = 0.0, containerRightX = 0.0, containerTopY = 0.0, containerBottomY = 0.0; /// 加号的key GlobalKey anchorKey = GlobalKey(); /// 加号的xy界限 late RenderBox anchorRenderBox; var anchorOffset; var anchorLeftX = 0.0, anchorRightX = 0.0, anchorTopY = 0.0, anchorBottomY = 0.0; /// 加号偏移量 var dx = 0.0.obs , dy = 0.0.obs; /// GETx特性
部分加号组件代码
Obx(()=>Transform.translate( key: anchorKey, offset: Offset(dx.value, 0), /// 不需要在线环境dy所以去掉了操作,可添加使用 child: Image.asset( R.imagesPlanIconAdd, width: 52.dp, ) ))
部分容器组件代码
/// 容器是白色的Container覆盖到紫色Container,形成的环,所以要把它放在key放在白色Container上 Container( key: controller.containerKey, decoration: BoxDecoration( color: c_FF, borderRadius: BorderRadius.all( Radius.circular(30.0), ), ), )
假设和已绑定相应的key。
accelerometerEvents.listen((AccelerometerEvent event) { acceleration = event; }); _timer = Timer.periodic(const Duration(milliseconds: 10), (_) { /// 该段主要用于获取容器的边界坐标 if(containerOffset == null && containerKey.currentContext != null){ /// 第一次进入页面时,会出现空值,所以不操作 containerRenderBox = containerKey.currentContext!.findRenderObject() as RenderBox; containerOffset = containerRenderBox.localToGlobal(Offset.zero); containerLeftX = containerOffset?.dx; containerRightX = containerOffset?.dx; containerRightX = containerOffset?.dx containerRenderBox.size.width; containerTopY = containerOffset?.dy; containerBottomY = containerOffset?.dy containerRenderBox.size.height; } /// 该段主要用于获取加号边界坐标 if(anchorOffset == null && anchorKey.currentContext != null){ anchorRenderBox = anchorKey.currentContext!.findRenderObject() as RenderBox; anchorOffset = anchorRenderBox.localToGlobal(Offset.zero); anchorLeftX = anchorOffset?.dx; anchorRightX = anchorOffset?.dx anchorRenderBox.size.width; anchorTopY = anchorOffset?.dy; anchorBottomY = anchorOffset?.dy anchorRenderBox.size.height; } /// 刷新加号位置 if(acceleration != null && containerOffset != null && anchorOffset != null){ var dxNow = acceleration!.x.abs() < 1.0 ? dx.value : ((anchorLeftX (dx.value - acceleration!.x)) > containerLeftX) && (anchorRightX (dx.value - acceleration!.x)) < containerRightX ? dx.value - acceleration!.x : dx.value; var dyNow = acceleration!.y.abs() < 1.0 ? dy.value : ((anchorTopY (dy.value acceleration!.y)) > containerTopY) && (anchorBottomY (dy.value acceleration!.y)) < containerBottomY ? dy.value acceleration!.y : dy.value; dx.value = dxNow; dy.value = dyNow; } });
??:因为我用的GETx因此,当将状态管理框架包裹在容器外时Obx(()=>Container())
可自动刷新。如果不使用,则需要setState(() {})
刷新组件。