✅이번 시간에는 로그인과 주사위 앱 만들기에 대해서 알아볼 예정이야.
뭔가 생각보다 새로이 보는 것들이 많았고, 디자인 패턴이나 클린 코드에 대해서 플러터는 상당히 중요할 것 같다는 생각이 확 들었어.
코드를 보면서 그럼 함께 보도록 하자.
플러터 개발에 있어서, 코드를 쭉 읽어보면서 지나가자
✅플러터 화면 중 일부
✅main.dart
// main.dart
import 'package:flutter/material.dart';
import 'dice.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Dice game',
home: LogIn(),
);
}
}
class LogIn extends StatefulWidget {
@override
_LogInState createState() => _LogInState();
}
class _LogInState extends State<LogIn> {
TextEditingController controller1 =
TextEditingController(); // 텍스트 필드에 읿력된 값을 읽어야 할때
TextEditingController controller2 = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Log in'),
backgroundColor: Colors.redAccent,
centerTitle: true,
leading: IconButton(icon: Icon(Icons.menu), onPressed: () {}),
actions: <Widget>[
IconButton(icon: Icon(Icons.search), onPressed: () {})
],
),
body: Builder( // 스캐폴드 메신저를 날리기 위해서 Builder가 필요해
builder: (context) {
return GestureDetector( // 화면 터치하는거 감지하게끔 - 이렇게 해서 키보드 밖에 터치지 작동하게끔 만들려고
onTap: () {
FocusScope.of(context).unfocus(); // 화면에 빈 공간 클릭하면 여기 하위에 걸리는 위젯들이 포커스 다 놓게끔 만들기
},
child: SingleChildScrollView(
// 키보드가 화면을 가리는데 키보드가 올라오면서 스크롤이 가능하게끔 바꿔줌
child: Column(
children: [
Padding(padding: EdgeInsets.only(top: 50)),
Center(
child: Image(
image: AssetImage('image/chef.gif'),
width: 170,
height: 190,
),
),
Form(
// 웹에서 Form 형식 보이던데, 데이터를 전달하기 위한 코드
child: Theme(
data: ThemeData(
primaryColor: Colors.teal,
inputDecorationTheme: InputDecorationTheme( // 입력하는 부분 커스텀
labelStyle: TextStyle(
color: Colors.teal, fontSize: 15.0))),
child: Container(
padding: EdgeInsets.all(40.0),
child: Column(
children: [
TextField(
//autofocus: true, // 포커스 자동으로 잡기 - 키보드 내려가게 구현하려
controller: controller1,
decoration:
InputDecoration(labelText: 'Enter "dice"'),
keyboardType:
TextInputType.emailAddress, // 키보드 타입
),
TextField(
controller: controller2,
decoration:
InputDecoration(labelText: 'Enter Password'),
// 텍스트 필드 위의 레이블 keyboardType: TextInputType.text, // 키보드 타입
obscureText: true, // 텍스트 필드 입력할 때 비밀번호 점으로 바뀌게끔
),
SizedBox(
height: 40.0,
),
ButtonTheme(
// 버튼 데이터를 받기 위함.
minWidth: 100, // 최소 너비
height: 50,
child: ElevatedButton(
onPressed: () {
if (controller1.text == 'dice' &&
controller2.text == '1234') {
Navigator.push(
context,
MaterialPageRoute(
builder:
(BuildContext context) =>
Dice()));
} else if (controller1.text != 'dice' &&
controller2.text == '1234') {
showSnackBar2(context);
} else if (controller1.text == 'dice' &&
controller2.text != '1234') {
showSnackBar3(context);
} else {
showSnackBar(context);
}
},
child: Icon(Icons.arrow_forward),
style: ElevatedButton.styleFrom(
primary: Colors.orangeAccent,
),
))
],
),
),
),
)
],
),
),
);
},
));
}
}
void showSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(// 스캐폴드메신저 만들기
// 가장 가까운 스캐폴드 찾아서 반환해
SnackBar(
// 스낵바
content: Text('로그인 정보 다시 확인해'), // 내
duration: Duration(seconds: 2),
backgroundColor: Colors.blue,
));
}
void showSnackBar2(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(// 스캐폴드메신저 만들기
// 가장 가까운 스캐폴드 찾아서 반환해
SnackBar(
// 스낵바
content: Text('dice 철자 확인해'), //
duration: Duration(seconds: 2),
backgroundColor: Colors.blue,
));
}
void showSnackBar3(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar(// 스캐폴드메신저 만들기
// 가장 가까운 스캐폴드 찾아서 반환해
SnackBar(
// 스낵바
content: Text('비밀번호 불일치'),
duration: Duration(seconds: 5),
backgroundColor: Colors.blue,
));
}
✅dice.dart
// dice.dart
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:fluttertoast/fluttertoast.dart';
class Dice extends StatefulWidget {
@override
_DiceState createState() => _DiceState();
}
class _DiceState extends State<Dice> {
int leftDice = 1;
int rightDice = 1;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.redAccent,
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text('Dice game'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.all(32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded( // 화면 최대 길이로 요소 확
//flex: 2, // 웹에서 해봤으면 flex 통해서 이미지 비율 조정가능
child: Image.asset('image/dice$leftDice.png')),
// 가로방향 끝까지 확장
SizedBox(
width: 20,
),
Expanded(child: Image.asset('image/dice$rightDice.png')),
// 이미지 2개면 나눠서 가져감
],
),
),
SizedBox(
height: 20,
),
ButtonTheme( // 버튼의 모양 같은거 조정할 때 이걸로 감쌈
minWidth: 100.0,
height: 60.0,
child: ElevatedButton(
onPressed: () {
setState(() {
leftDice = Random().nextInt(6) + 1;
rightDice = Random().nextInt(6) + 1;
});
showToast('Left Dice $leftDice , Right Dice $rightDice');
},
child: Icon(Icons.play_arrow),
style: ElevatedButton.styleFrom(
primary: Colors.orangeAccent,
),
),
)
],
)),
);
}
}
void showToast(String message) {
Fluttertoast.showToast(
msg: message,
backgroundColor: Colors.grey,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
);
}
'flutter > 조금 매운맛 (중급)' 카테고리의 다른 글
[flutter2.0] 12강 | Future-async 심화 (0) | 2021.08.23 |
---|---|
[flutter2.0] 8강 - 2 | APICall & JsonParsing (0) | 2021.08.17 |
[flutter2.0] 8강 - 1 | Future, async, await 이해하기 (0) | 2021.08.17 |
[flutter2.0] 7강 | 로그인 페이지 코드 리팩토링(refactoring) (0) | 2021.08.17 |
[flutter2.0] 1강~2강 | Stateful widget (0) | 2021.08.16 |