중력을 포함한 장치의 속도를 알려주는 센서. 특정방향으로 움직이는지 알 수 있다. 수평계는 이걸 사용해 만든다.
속도에서 중력을 제외한 채 속도를 알려주는 센서.
장치의 회전을 나타내는 센서.
장치를 둘러싼 자기장을 나타내는 센서. 나침반은 이걸 사용해 만든다.
https://pub.dev/packages/sensors_plus
공식문서에 나와 있는 일회성 스트림을 쓸 수도 있고, 스트림 빌더를 사용할 수도 있다.
일회성 스트림을 사용할 때의 코드는 아래와 같다.
void initState() {
super.initState();
_streamSubscriptions.add(
accelerometerEvents.listen(
(AccelerometerEvent event) {
setState(() {
_accelerometerValues = <double>[event.x, event.y, event.z];
});
},
),
);
}
이 코드의 경우 x축을 사용할 때는 _accelerometerValues[0]이고, y축은 _accelerometerValues[1]이 된다. 그러나 매번 사용하고 streamSubscriptions을 dispose해야 하는 번거로움이 있다.
그래서 Streambuilder를 사용한 코드를 쓰면 다음과 같다.
StreamBuilder<AccelerometerEvent>(
stream: SensorsPlatform.instance.accelerometerEvents,
builder: (context, snapshot) {
if (snapshot.hasData) {
posX = posX + (snapshot.data!.x * 10);
if (posX > width) {
posX = width;
} else if (posX < 0) {
posX = 0;
}
posY = posY + (snapshot.data!.y * 10);
if (posY > height) {
posY = height;
} else if (posY < 0) {
posY = 0;
}
}
그러나 여기서 문제가 생긴다. accelerometer를 사용하면 경사도를 알려주는 공이 화면밖으로 나가서 들어오지 않는다는 점이다. 그래서 GyroscopeEvent로 바꿔줬더니 잘 작동되었다.
이 둘은 옮기기냐 연속이동이냐의 차이다.
Transform.position은 옮기기기 때문에 지정 위치로 순간이동만 된다.
Transform.translate는 연속이동이기 때문에 일정 속도를 가지고 일정 거리만큼씩 연속으로 이동한다. 공모양의 이동에 사용했다.
return Transform.translate(
offset: Offset(posX, posY),
child: const CircleAvatar(
radius: 20,
backgroundColor: Colors.red,
),
);