본문 바로가기
  • 인공지능
  • 블록체인
  • 정보보안
코딩 알로하 :: two/하이브리드앱

패스트캠퍼스 챌린지 24일차

by nathan03 2021. 11. 24.
반응형

# 강의 제목 : 누적다운로드 120만+ 1인 개발자와 함께하는 앱 개발 입문 Online

# 강의 목표 : 기초부터 운영까지 앱 개발의 전체 프로세스를 이해한다. 
                  내 이름으로 된 앱을 최대 10개까지 만들어 출시할 수 있다. 
                  앱 개발자로 성장할 수 있는 초석을 다진다. 
                  반응 얻는 앱의 특징과 노하우를 알아간다. 
                  향후 강의 없이도 나만의 앱을 개발할수 있는 실력을 가진다. 

# 강의 요약 : 프로그램 설치부터 기본 문법, 광고 다는 법, 클론코딩을 진행하며 필수 지식을 학습한다. 
                 총 10개의 다른 주제로 실제 사용화 가능한 수준의 앱을 만들어본다.
                 나의 앱을 세상에 선보이기 위한 개발자 등록 및 배포를 진행한다. 
                 강사님의 리뷰/클레임 대응사례 등 앱 성공 포인트를 참고해 1인 개발자로서의 입지를 다진다. 

 # 강의 목차 : Flutter 실전 앱 제작
                    - 앱 기능 및 디자인 설계 및 초기 구조 만들기 (옷추천앱)
                    - 날씨 데이터 모델링 
                    - 날씨 화면 만들기 1 - 24일차 
                    - 날씨 화면 만들기 2 - 24일차 
                    - 날씨별 커스텀
                    - 나만의 옷장
                         

# 강의 화면 : 

 

# 강의 내용 : 날씨 화면 만들기 1, 2

1. 앱 디자인 설계 

2. 이미지 assets 추가하기 
경로 : assets > img 

pubspec.yaml 파일 경로 반영 하기 

flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/img/
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

3. 화면 이미지 구현하기 

# main.dart 

import 'package:cloth/cloth.dart';
import 'package:cloth/data/api.dart';
import 'package:cloth/data/preference.dart';
import 'package:cloth/data/weather.dart';
import 'package:cloth/location.dart';
import 'package:cloth/utils.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      debugShowCheckedModeBanner: false,
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);


  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  List<String> clothes = ["assets/img/shirt.png", "assets/img/short.png", "assets/img/pants.png"];
  List<Weather> weather =[];
  List<ClothTmp> tmpCloth = [];
  Weather current;
  LocationData location = LocationData(lat: 37.498122, lng: 127.027565, name: "강남구", x: 0, y: 0);
  List<String> sky = [
    "assets/img/sky1.png",
    "assets/img/sky2.png",
    "assets/img.sky3.png",
    "assets/img/sky4.png"];
  List<String> status = [
    "날이 아주 좋아요!",
    "산책하기 좋겠어요",
    "오늘은 흐리네요",
    "우산 꼭 챙겨요!!"];

  List<Color> color = [
    Color(0xFFf78144),
    Color(0xFF1d9fea),
    Color(0xFF523de4),
    Color(0xFF587d9a)
  ];
  int level = 0;

  void getWeather() async {
    final api = WeatherApi();
    final now = DateTime.now();
    Map<String, int> xy = Utils.latLngToXY(location.lat, location.lng);

    final pref = Preference();
    tmpCloth = await pref.getTmp();

    int time2 = int.parse("${now.hour}10");
    String _time = "";

    if(time2 > 2300){
      _time = "2300";
    }else if(time2 > 2000){
      _time = "2000";
    }else if(time2 > 1700){
    _time = "1700";
    }else if(time2 > 1400){
    _time = "1400";
    }else if(time2 > 1100){
    _time = "1100";
    }else if(time2 > 800){
    _time = "0800";
    }else if(time2 > 500){
    _time = "0500";
    }else {
      _time = "0200";
    }



    weather = await api.getWeather(xy["nx"], xy["ny"], Utils.getFormatTime(DateTime.now()), _time);

    int time = int.parse("${now.hour}00");
    weather.removeWhere((w) => w.time < time);
    current = weather.first;

    clothes = tmpCloth.firstWhere((t) => t.tmp < current.tmp).cloth;

    level = getLevel(current);
    setState(() {});

  }

  int getLevel(Weather w){
    if(w.sky > 8){
      return 3;
    }
    else if(w.sky > 5){
      return 2;
    }else if(w.sky > 2){
      return 1;
    }

    return 0;
  }

  @override
  void initState() {
    super.initState();
    getWeather();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        actions: [
          IconButton(icon: Icon(Icons.category),
          onPressed: () async {
            await Navigator.of(context).push(
              MaterialPageRoute(builder: (ctx) => ClothPage())
            );
            getWeather();
          },)
        ],
      ),
      backgroundColor: color[level],
      body: weather.isEmpty ? Container(child: Text("날씨 정보를 불러오고 있어요")) :
      Container(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Container(height: 50,),
            Text("${location.name}", textAlign: TextAlign.center,
              style: TextStyle(
                  color: Colors.white,
                  fontSize: 20
              ),),
            Container(
              width: 100,
              height: 100,
              margin: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
              child: Image.asset(sky[level]),
              alignment: Alignment.centerRight,
            ),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                Text("${current.tmp}°C", style: TextStyle(
                    color: Colors.white,
                    fontSize: 28
                )),
                Column(
                  children: [
                    Text("${Utils.stringToDateTime(current.date).month}월 ${Utils.stringToDateTime(current.date).day}일", style: TextStyle(
                        color: Colors.white,
                        fontSize: 14
                    )),
                    Text(status[level], style: TextStyle(
                        color: Colors.white,
                        fontSize: 14
                    )),
                  ],
                )
              ],
            ),
            Container(height: 30,),
            Container(child: Text("오늘 어울리는 복장을 추천해드려요", style: TextStyle(
                color: Colors.white,
                fontSize: 18
            )),
              margin: EdgeInsets.symmetric(horizontal: 20),
            ),
            Container(height: 30,),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: List.generate(clothes.length, (idx){
                return Container(
                  padding: EdgeInsets.all(8),
                  width: 100,
                  height: 100,
                  child: Image.asset(clothes[idx], fit: BoxFit.contain,),
                );
              }),
            ),
            Container(height: 30,),
            Expanded(child: Container(
                height: 150,
                child: ListView(
                  scrollDirection: Axis.horizontal,
                  children: List.generate(
                      weather.length,
                          (idx){

                        final w = weather[idx];
                        int _level = getLevel(w);

                        return Container(
                          margin: EdgeInsets.symmetric(horizontal: 8),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            mainAxisAlignment: MainAxisAlignment.end,
                            children: [
                              Text("${w.tmp}°C", style: TextStyle(fontSize: 10, color: Colors.white),),
                              Text("${w.pop}%", style: TextStyle(fontSize: 10, color: Colors.white)),
                              Container(
                                width: 50,
                                height: 50,
                                child: Image.asset(sky[_level]),
                              ),
                              Text("${w.time}", style: TextStyle(fontSize: 10, color: Colors.white)),
                            ],
                          ),
                        );
                      }
                  ),
                ))),
            Container(height: 80,),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          LocationData data = await Navigator.of(context).push(
            MaterialPageRoute(builder: (ctx) => LocationPage())
          );
          if(data != null){
            location = data;
            getWeather();
          }
        },
        tooltip: 'Increment',
        child: Icon(Icons.location_on),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

                  
# util.dart

import 'dart:math' as math;

class Utils {
  static String makeTwoDigit(int number){
    return number.toString().padLeft(2, "0");
  }

  static int getFormatTime(DateTime time){
    return int.parse("${time.year}${makeTwoDigit(time.month)}${makeTwoDigit(time.day)}");
  }

  static DateTime stringToDateTime(String date){
    int year = int.parse(date.substring(0, 4));
    int month = int.parse(date.substring(4, 6));
    int day = int.parse(date.substring(6, 8));

    return DateTime(year, month, day);
  }
}

하늘 상태 레벨

  int getLevel(Weather w){
    if(w.sky > 8){
      return 3;
    }
    else if(w.sky > 5){
      return 2;
    }else if(w.sky > 2){
      return 1;
    }

    return 0;
  }


# 교육 소감

# 본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

https://bit.ly/3FVdhDa

 

수강료 100% 환급 챌린지 | 패스트캠퍼스

딱 5일간 진행되는 환급챌린지로 수강료 100% 환급받으세요! 더 늦기전에 자기계발 막차 탑승!

fastcampus.co.kr

반응형

댓글