0131_코드팩토리 플러터 프로그래밍 cpt11
가속도계 및 자일로스코프
sensor_plus 패키지를 사용하면 핸드폰의 가속도계와 자일로스코프 센서를 사용할 수 있다.
shake 플러그인을 사용하여 핸드폰 흔들기를 사용할 수 있다.
전체소스
main.dart
import 'package:flutter/material.dart';
import 'package:random_dice/screen/home_screen.dart';
import 'package:random_dice/const/colors.dart';
import 'package:random_dice/screen/root_screen.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
scaffoldBackgroundColor: backgroundColor,
sliderTheme: SliderThemeData( // Slider 위젯 관련
thumbColor: primaryColor, // 동그라미 색
activeTrackColor: primaryColor, // 이동한 트랙 색
// 아직 이동하지 않은 트랙 색
inactiveTrackColor: primaryColor.withOpacity(0.3), ),
// BottomNavigationBar 위젯 관련
bottomNavigationBarTheme: BottomNavigationBarThemeData(
selectedItemColor: primaryColor, // 선택 상태 색
unselectedItemColor: secondaryColor, // 비선택 상태 색
backgroundColor: backgroundColor, // 배경 색
),
),
home: RootScreen(),
),
);
}
home_screen.dart
import 'package:random_dice/const/colors.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
final int number;
const HomeScreen({
required this.number,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// ➊ 주사위 이미지
Center(
child: Image.asset('asset/img/$number.png'),
),
SizedBox(height: 32.0),
Text(
'행운의 숫자',
style: TextStyle(
color: secondaryColor,
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
SizedBox(height: 12.0),
Text(
number.toString(), // ➋ 주사위 값에 해당되는 숫자
style: TextStyle(
color: primaryColor,
fontSize: 60.0,
fontWeight: FontWeight.w200,
),
),
],
);
}
}
root_screen.dart
import 'package:flutter/material.dart';
import 'package:random_dice/screen/home_screen.dart';
import 'package:random_dice/screen/settings_screen.dart';
import 'dart:math';
import 'package:shake/shake.dart';
class RootScreen extends StatefulWidget {
const RootScreen({Key? key}) : super(key: key);
@override
State<RootScreen> createState() => \_RootScreenState();
}
class \_RootScreenState extends State<RootScreen> with TickerProviderStateMixin{ // ➊
TabController? controller; // 사용할 TabController 선언
double threshold = 2.7;
int number = 1;
ShakeDetector? shakeDetector;
@override
void initState() {
super.initState();
controller = TabController(length: 2, vsync: this); // ➋
controller!.addListener(tabListener);
shakeDetector = ShakeDetector.autoStart( // ➊ 흔들기 감지 즉시 시작
shakeSlopTimeMS: 100, // ➋ 감지 주기
shakeThresholdGravity: threshold, // ➌ 감지 민감도
onPhoneShake: onPhoneShake, // ➍ 감지 후 실행할 함수
);
}
void onPhoneShake() { // ➎ 감지 후 실행할 함수
final rand = new Random();
setState(() {
number = rand.nextInt(5) + 1;
});
}
tabListener() { // ➋ listener로 사용할 함수
setState(() {});
}
@override
dispose(){
controller!.removeListener(tabListener); // ➌ listener에 등록한 함수 등록 취소
shakeDetector!.stopListening();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: TabBarView( // ➊ 탭 화면을 보여줄 위젯
controller: controller,
children: renderChildren(),
),
// ➋ 아래 탭 네비게이션을 구현하는 매개변수
bottomNavigationBar: renderBottomNavigation(),
);
}
List<Widget> renderChildren(){
return [
HomeScreen(number: number),
SettingsScreen( // 기존에 있던 Container 코드를 통째로 교체
threshold: threshold,
onThresholdChange: onThresholdChange,
),
];
}
void onThresholdChange(double val){ // ➊ 슬라이더값 변경 시 실행 함수
setState(() {
threshold = val;
});
}
BottomNavigationBar renderBottomNavigation() {
return BottomNavigationBar(
currentIndex: controller!.index,
onTap: (int index) { // ➎ 탭이 선택될 때마다 실행되는 함수
setState(() {
controller!.animateTo(index);
});
},
items: [
BottomNavigationBarItem( // ➊ 하단 탭바의 각 버튼을 구현
icon: Icon(
Icons.edgesensor_high_outlined,
),
label: '주사위',
),
BottomNavigationBarItem(
icon: Icon(
Icons.settings,
),
label: '설정',
),
],
);
}
}
setting_screen.dart
import 'package:random_dice/const/colors.dart';
import 'package:flutter/material.dart';
class SettingsScreen extends StatelessWidget {
final double threshold; // Slider의 현잿값
// Slider가 변경될 때마다 실행되는 함수
final ValueChanged<double> onThresholdChange;
const SettingsScreen({
Key? key,
// threshold와 onThresholdChange는 SettingsScreen에서 입력
required this.threshold,
required this.onThresholdChange,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 20.0),
child: Row(
children: [
Text(
'민감도',
style: TextStyle(
color: secondaryColor,
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
],
),
),
Slider(
min: 0.1, // ➊ 최솟값
max: 10.0, // ➋ 최댓값
divisions: 101, // ➌ 최솟값과 최댓값 사이 구간 개수
value: threshold, // ➍ 슬라이더 선택값
onChanged: onThresholdChange, // ➎ 값 변경 시 실행되는 함수
label: threshold.toStringAsFixed(1), // ➏ 표싯값
),
],
);
}
}
colors.dart
import 'package:flutter/material.dart';
const backgroundColor = Color(0xFF0E0E0E); // 배경색
const primaryColor = Colors.white; // 주 색상
final secondaryColor = Colors.grey[600]; // 보조 색상
Leave a comment