# 강의 제목 : 누적다운로드 120만+ 1인 개발자와 함께하는 앱 개발 입문 Online
# 강의 목표 : 기초부터 운영까지 앱 개발의 전체 프로세스를 이해한다.
내 이름으로 된 앱을 최대 10개까지 만들어 출시할 수 있다.
앱 개발자로 성장할 수 있는 초석을 다진다.
반응 얻는 앱의 특징과 노하우를 알아간다.
향후 강의 없이도 나만의 앱을 개발할수 있는 실력을 가진다.
# 강의 요약 : 프로그램 설치부터 기본 문법, 광고 다는 법, 클론코딩을 진행하며 필수 지식을 학습한다.
총 10개의 다른 주제로 실제 사용화 가능한 수준의 앱을 만들어본다.
나의 앱을 세상에 선보이기 위한 개발자 등록 및 배포를 진행한다.
강사님의 리뷰/클레임 대응사례 등 앱 성공 포인트를 참고해 1인 개발자로서의 입지를 다진다.
# 강의 목차 : Flutter 실전 앱 제작
- 앱 기능 및 디자인 설계 및 초기 구조 만들기 (눈바디앱)
- 식단 기록 페이지 - 27일차
- 눈바디 운동 기록 페이지 - 27일차
- 달력 기록 페이지
- 달력 기록 페이지 2
- 통계 갤러리 알림 설정하기
- 다크모드 지원하기
# 강의 화면 :
# 강의 내용 : 식단 기록 페이지 및 눈바디 운동 기록 페이지
1. 화면 디자인
- 각각 칼로리, 몸무게, 운동시간 등 부가 페이지에서 데이터를 호출하여 메인 페이지로 불러오도록 작성한다.
# main.dart
class _MyHomePageState extends State<MyHomePage> {
int currentIndex = 0;
FirebaseAnalytics analytics = FirebaseAnalytics();
List<Food> todayFood = [];
List<Workout> todayWorkout = [];
List<EyeBody> todayEyeBody = [];
CalendarController controller = CalendarController();
final dbHelper = DatabaseHelper.instance;
DateTime time = DateTime.now();
void getHistories() async {
int d = Utils.getFormatTime(time);
todayFood = await dbHelper.queryFoodByDate(d);
todayWorkout = await dbHelper.queryWorkoutByDate(d);
todayEyeBody = await dbHelper.queryEyeBodyByDate(d);
setState(() {
});
analytics.setUserProperty(name: "sex", value: "남자");
analytics.setUserProperty(value: "여자", name: "sex");
}
# food.dart
import 'package:eyebody/data/data.dart';
import 'package:eyebody/data/database.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
class FoodAddPage extends StatefulWidget {
final Food food;
FoodAddPage({Key key, this.food}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _FoodAddPageState();
}
}
class _FoodAddPageState extends State<FoodAddPage> {
TextEditingController kcalController = TextEditingController();
TextEditingController memoController = TextEditingController();
Food get food => widget.food;
@override
void initState() {
kcalController.text = food.kcal.toString();
memoController.text = food.memo;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
TextButton(child: Text("저장", style: TextStyle(color: Colors.white)),
onPressed: () async {
food.memo = memoController.text;
food.kcal = int.tryParse(kcalController.text) ?? 0;
final dbHelper = DatabaseHelper.instance;
await dbHelper.insertFood(food);
Navigator.of(context).pop();
},
)
],
),
body: Container(
child: ListView.builder(
itemBuilder: (ctx, idx){
if(idx == 0){
return Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Text("오늘 어떤 음식을 드셨나요?", style: TextStyle(fontSize: 20,
color: Colors.white
),
),
);
}
else if(idx == 1){
return Container(
margin: EdgeInsets.symmetric(horizontal: 16, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("칼로리", style: TextStyle(fontSize: 16,
color: Colors.white
),),
Container(child: TextField(
controller: kcalController,
inputFormatters: [
FilteringTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
border: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white)
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white)
)
),
keyboardType: TextInputType.number,
), width: 100,)
],
),
);
}
else if(idx == 2){
return Container(
margin: EdgeInsets.symmetric(vertical: 0, horizontal: 20),
width: 300,
height: 300,
child: Container(child: Align(
alignment: Alignment.center,
child: InkWell(
child: AspectRatio(child: food.image.isEmpty ? Image.asset("assets/img/rice.png") :
AssetThumb(asset: Asset(food.image, "food.png", 0, 0), width: 300, height: 300),
aspectRatio: 1,
),
onTap: (){
selectImage();
},
),
)),
);
}
else if(idx == 3){
return Container(
margin: EdgeInsets.symmetric(vertical: 16, horizontal: 20),
child: CupertinoSegmentedControl(
children: {
0: Text("아침"),
1: Text("점심"),
2: Text("저녁"),
3: Text("간식"),
},
onValueChanged: (idx){
setState(() {
food.type = idx;
});
},
groupValue: food.type,
),
);
}
else if(idx == 4){
return Container(
margin: EdgeInsets.symmetric(vertical: 16, horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text("메모", style: TextStyle(fontSize: 16, color: Colors.white),),
Container(height: 12,),
TextField(
maxLines: 10,
minLines: 10,
keyboardType: TextInputType.multiline,
controller: memoController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.white)
)
),
)
],
),
);
}
return Container();
},
itemCount: 5,
),
),
);
}
Future<void> selectImage() async {
final __img = await MultiImagePicker.pickImages(maxImages: 1, enableCamera: true);
if(__img.length < 1){
return;
}
setState(() {
food.image = __img.first.identifier;
});
}
}
# 교육 소감
# 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
'코딩 알로하 :: two > 하이브리드앱' 카테고리의 다른 글
패스트캠퍼스 챌린지 29일차 (0) | 2021.11.29 |
---|---|
패스트캠퍼스 챌린지 28일차 (0) | 2021.11.28 |
패스트캠퍼스 챌린지 26일차 (0) | 2021.11.26 |
패스트캠퍼스 챌린지 25일차 (0) | 2021.11.25 |
패스트캠퍼스 챌린지 24일차 (0) | 2021.11.24 |
댓글