
(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 + 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(() {}) 刷新组件。
|