Future

2024. 6. 18. 12:56Flutter

 

✅ 학습 목표

 

✅ 동기방식과 비동기방식

 

✅ future 예시

import 'dart:io';

void main() {
  orderProcess();
  waiting();
}

void orderProcess() async {
  // 주문에 대한 절차 설계
  kiosk();
  orderFood();
  await getFood(); // Future<String> 형태로 선언!
  goHome();
}

void kiosk() {
  print('키오스크 사용하기');
}

void orderFood() {
  print('햄버거 주문하기');
}

// Future 사용시 함께 사용되는 키워드! -> await, async
Future<String> getFood() async {
  Duration delay = Duration(seconds: 4); // delay를 줄 때 사용
  // sleep(delay);

  String menu = '햄버거'; // 코드는 위에서 아래로 진행하기 때문에 먼저 선언!

  // delay 값을 비동기 방식으로 사용할 수 있도록 설계!
  await Future.delayed(delay, (){
    print('${menu} 받기');
  });

  return menu;
}

void goHome() {
  print('햄버거 들고 집에 가기');
}

void waiting() {
  print('앉아서 핸드폰 보기');
}

 

✅ Future, async / await 정리

 

✅ Json 데이터 사용

 

✅ Json Pasing 실습

http: ^1.2.1

<!--  인터넷 통신을 위한 권한 설정하기  -->
    <uses-permission android:name="android.permission.INTERNET" />

 

✅ Json 데이터 사용

// To parse this JSON data, do
//
//     final user = userFromJson(jsonString);

import 'dart:convert';

List<User> userFromJson(String str) =>
    List<User>.from(json.decode(str).map((x) => User.fromJson(x)));

String userToJson(List<User> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class User {
  int id;
  String name;
  String username;
  String email;
  Address address;
  String phone;
  String website;
  Company company;

  User({
    required this.id,
    required this.name,
    required this.username,
    required this.email,
    required this.address,
    required this.phone,
    required this.website,
    required this.company,
  });

  factory User.fromJson(Map<String, dynamic> json) => User(
        id: json["id"],
        name: json["name"],
        username: json["username"],
        email: json["email"],
        address: Address.fromJson(json["address"]),
        phone: json["phone"],
        website: json["website"],
        company: Company.fromJson(json["company"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "username": username,
        "email": email,
        "address": address.toJson(),
        "phone": phone,
        "website": website,
        "company": company.toJson(),
      };
}

class Address {
  String street;
  String suite;
  String city;
  String zipcode;
  Geo geo;

  Address({
    required this.street,
    required this.suite,
    required this.city,
    required this.zipcode,
    required this.geo,
  });

  factory Address.fromJson(Map<String, dynamic> json) => Address(
        street: json["street"],
        suite: json["suite"],
        city: json["city"],
        zipcode: json["zipcode"],
        geo: Geo.fromJson(json["geo"]),
      );

  Map<String, dynamic> toJson() => {
        "street": street,
        "suite": suite,
        "city": city,
        "zipcode": zipcode,
        "geo": geo.toJson(),
      };
}

class Geo {
  String lat;
  String lng;

  Geo({
    required this.lat,
    required this.lng,
  });

  factory Geo.fromJson(Map<String, dynamic> json) => Geo(
        lat: json["lat"],
        lng: json["lng"],
      );

  Map<String, dynamic> toJson() => {
        "lat": lat,
        "lng": lng,
      };
}

class Company {
  String name;
  String catchPhrase;
  String bs;

  Company({
    required this.name,
    required this.catchPhrase,
    required this.bs,
  });

  factory Company.fromJson(Map<String, dynamic> json) => Company(
        name: json["name"],
        catchPhrase: json["catchPhrase"],
        bs: json["bs"],
      );

  Map<String, dynamic> toJson() => {
        "name": name,
        "catchPhrase": catchPhrase,
        "bs": bs,
      };
}

 

✅ Json Parsing

import 'package:flutter/material.dart';
import 'package:http/http.dart';

import 'UserModel.dart';

// 통신이 필요하다! -> Stateful 설계!
// 통신을 진행할 경우 필요한 라이브러리! -> http 라이브러리!
class ExJson extends StatefulWidget {
  const ExJson({super.key});

  @override
  State<ExJson> createState() => _ExJsonState();
}

class _ExJsonState extends State<ExJson> {
  // 대량의 데이터를 담을 수 있는 리스트 구조 선언!
  List<User> userList = [];

  // 데이터 통신 시도!
  Future<List<User>> getInfo() async {
    // 통신을 [요청 -> request]할 url 주소 필요! -> String 타입으로 지정!
    String url = "https://jsonplaceholder.typicode.com/users";

    // 요청 url로부터 [응답 -> response]값 받아오기!
    var res = await get(Uri.parse(url));
    print(res.statusCode); // 200 -> 응답이 확인 된다
    // 200 코드 : 응답 성공시!
    // 500 코드 : 데이터에 문제가 있을 경우
    // 404 코드 : 페이지에 대한 오류

    // print("res : $res"); // res : Instance of 'Response'

    userList = userFromJson(res.body); // res.body -> res가 담은 값 중 몸체만 가져오겠다
    print(userList[0].address.city); // Gwenborough
    // print(userList[0].name); // Leanne Graham
    // print(userList[0]); Instance of 'User'

    return userList;
  }

  @override
  Widget build(BuildContext context) {
    getInfo(); // 호출해서 사용할거기 때문에 필요!
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder(
          future: getInfo().then((value) => userList = value),
          builder: (context, snapshot) { // snapshot : 결과 값!
            // 통신의 상태에 따라 화면을 설계 할 수 있는지 없는지 판단!
            if (!snapshot.hasData) { // 데이터가 없다면
              // 로딩 화면 띄우기
              return Center(child: CircularProgressIndicator()); // 동그랗게 돌아가는 progress
            } else { // 데이터를 가지고 있다면
              // 띄워줄 데이터가 있다면 해당 내용을 화면으로 return!
              return ListView.builder(
                  itemCount: userList.length,
                  itemBuilder: (context, index){
                    return ListTile(
                      title: Text(userList[index].name),
                      leading: Icon(Icons.account_circle, color: Colors.orange,),
                      subtitle: Text(userList[index].address.city),
                      trailing: Icon(Icons.android, color: Colors.lightGreen,),

                    );
                  });
            }
          },
        ), // future -> 데이터, builder -> 디자인
      ),
    );
  }
}

 

✅ Weather App 만들기

geolocator: ^12.0.0

<!--  위치에 대한 권한 설정하기  -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARES_LOCATION" />

 

✅ setting.gradle 버전 업데이트

pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "7.3.0" apply false
    id "org.jetbrains.kotlin.android" version "2.0.0" apply false
}

include ":app"

import 'package:flutter/material.dart';
import 'package:http/http.dart';

class ExWeather extends StatelessWidget {
  // StatelessWidget 뒤에서 ctrl + space -> 2번째 material 클릭!
  const ExWeather({super.key});

  @override
  Widget build(BuildContext context) {
    getWeaterData();
    return const Placeholder();
  }
}

void getWeaterData() async {
  Response res = await get(Uri.parse(
      "https://api.openweathermap.org/data/2.5/weather?lat=35.14537&lon=126.919163&appid=&units=metric"));
  print(res.statusCode);

  if (res.statusCode == 200) {

  }

  print(res.body); // res.body --> String # 해당 결과 값들 받아오기
}

import 'package:flutter/material.dart';
import 'package:flutter0619/Weather/SampleWeather.dart';
import 'package:http/http.dart';

class ExWeather extends StatelessWidget {
  // StatelessWidget 뒤에서 ctrl + space -> 2번째 material 클릭!
  const ExWeather({super.key});

  @override
  Widget build(BuildContext context) {
    getWeaterData();
    return const Placeholder();
  }
}

void getWeaterData() async {
  Response res = await get(Uri.parse(
      "https://api.openweathermap.org/data/2.5/weather?lat=35.14537&lon=126.919163&appid=5b7403969c39771b3a9b321993fe9666&units=metric"));
  print(res.statusCode);

  if (res.statusCode == 200) {

  }

  print(res.body); // res.body --> String # 해당 결과 값들 받아오기

  SampleWeather w = sampleWeatherFromJson(res.body);
  print(w.main.temp);
}
import 'dart:convert';

SampleWeather sampleWeatherFromJson(String str) => SampleWeather.fromJson(json.decode(str));

String sampleWeatherToJson(SampleWeather data) => json.encode(data.toJson());

class SampleWeather {
  Coord coord;
  List<Weather> weather;
  String base;
  Main main;
  int visibility;
  Wind wind;
  Clouds clouds;
  int dt;
  Sys sys;
  int timezone;
  int id;
  String name;
  int cod;

  SampleWeather({
    required this.coord,
    required this.weather,
    required this.base,
    required this.main,
    required this.visibility,
    required this.wind,
    required this.clouds,
    required this.dt,
    required this.sys,
    required this.timezone,
    required this.id,
    required this.name,
    required this.cod,
  });

  factory SampleWeather.fromJson(Map<String, dynamic> json) => SampleWeather(
    coord: Coord.fromJson(json["coord"]),
    weather: List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
    base: json["base"],
    main: Main.fromJson(json["main"]),
    visibility: json["visibility"],
    wind: Wind.fromJson(json["wind"]),
    clouds: Clouds.fromJson(json["clouds"]),
    dt: json["dt"],
    sys: Sys.fromJson(json["sys"]),
    timezone: json["timezone"],
    id: json["id"],
    name: json["name"],
    cod: json["cod"],
  );

  Map<String, dynamic> toJson() => {
    "coord": coord.toJson(),
    "weather": List<dynamic>.from(weather.map((x) => x.toJson())),
    "base": base,
    "main": main.toJson(),
    "visibility": visibility,
    "wind": wind.toJson(),
    "clouds": clouds.toJson(),
    "dt": dt,
    "sys": sys.toJson(),
    "timezone": timezone,
    "id": id,
    "name": name,
    "cod": cod,
  };
}

class Clouds {
  int all;

  Clouds({
    required this.all,
  });

  factory Clouds.fromJson(Map<String, dynamic> json) => Clouds(
    all: json["all"],
  );

  Map<String, dynamic> toJson() => {
    "all": all,
  };
}

class Coord {
  double lon;
  double lat;

  Coord({
    required this.lon,
    required this.lat,
  });

  factory Coord.fromJson(Map<String, dynamic> json) => Coord(
    lon: json["lon"]?.toDouble(),
    lat: json["lat"]?.toDouble(),
  );

  Map<String, dynamic> toJson() => {
    "lon": lon,
    "lat": lat,
  };
}

class Main {
  double temp;
  double feelsLike;
  double tempMin;
  double tempMax;
  int pressure;
  int humidity;
  int seaLevel;
  int grndLevel;

  Main({
    required this.temp,
    required this.feelsLike,
    required this.tempMin,
    required this.tempMax,
    required this.pressure,
    required this.humidity,
    required this.seaLevel,
    required this.grndLevel,
  });

  factory Main.fromJson(Map<String, dynamic> json) => Main(
    temp: json["temp"]?.toDouble(),
    feelsLike: json["feels_like"]?.toDouble(),
    tempMin: json["temp_min"]?.toDouble(),
    tempMax: json["temp_max"]?.toDouble(),
    pressure: json["pressure"],
    humidity: json["humidity"],
    seaLevel: json["sea_level"],
    grndLevel: json["grnd_level"],
  );

  Map<String, dynamic> toJson() => {
    "temp": temp,
    "feels_like": feelsLike,
    "temp_min": tempMin,
    "temp_max": tempMax,
    "pressure": pressure,
    "humidity": humidity,
    "sea_level": seaLevel,
    "grnd_level": grndLevel,
  };
}

class Sys {
  String country;
  int sunrise;
  int sunset;

  Sys({
    required this.country,
    required this.sunrise,
    required this.sunset,
  });

  factory Sys.fromJson(Map<String, dynamic> json) => Sys(
    country: json["country"],
    sunrise: json["sunrise"],
    sunset: json["sunset"],
  );

  Map<String, dynamic> toJson() => {
    "country": country,
    "sunrise": sunrise,
    "sunset": sunset,
  };
}

class Weather {
  int id;
  String main;
  String description;
  String icon;

  Weather({
    required this.id,
    required this.main,
    required this.description,
    required this.icon,
  });

  factory Weather.fromJson(Map<String, dynamic> json) => Weather(
    id: json["id"],
    main: json["main"],
    description: json["description"],
    icon: json["icon"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "main": main,
    "description": description,
    "icon": icon,
  };
}

class Wind {
  double speed;
  int deg;
  double gust;

  Wind({
    required this.speed,
    required this.deg,
    required this.gust,
  });

  factory Wind.fromJson(Map<String, dynamic> json) => Wind(
    speed: json["speed"]?.toDouble(),
    deg: json["deg"],
    gust: json["gust"]?.toDouble(),
  );

  Map<String, dynamic> toJson() => {
    "speed": speed,
    "deg": deg,
    "gust": gust,
  };
}

import 'package:flutter/material.dart';
import 'package:flutter0619/Weather/SampleWeather.dart';
import 'package:flutter0619/Weather/weather_main.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart';

// 위치 정보 파악
// 해당 위치에 맞는 날씨 가지고 오기

class LoadingPage extends StatelessWidget {
  const LoadingPage({super.key});

  @override
  Widget build(BuildContext context) {
    getLocation(context);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.lightBlue[100],
        elevation: 0.0, // AppBar가 떠 있는듯한 느낌을 줄 때 사용!
      ),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.lightBlue[100],
        child: Center(
          child: Container(
            child: CircularProgressIndicator(),
          ),
        ),
      ),
    );
  }
}

void getLocation(context) async {
  await Geolocator
      .requestPermission(); // requestPermission : 권한 설정 물어보는 코드 -> await가 꼭 필요!
  Position position = await Geolocator.getCurrentPosition();

  double lat = position.latitude;
  double lon = position.longitude;

  print("lat : $lat, lon : $lon");
  getWeather(lat, lon, context);
}

void getWeather(double lat, double lon, context) async {
  String url =
      "https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=5b7403969c39771b3a9b321993fe9666&units=metric";
  print(url);
  Response res = await get(Uri.parse(url));
  print(res.body);
  SampleWeather w = sampleWeatherFromJson(res.body);

  // 페이지 이동
  Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) {
    return WeatherMain();
  }), (route) => false);
}

name: flutter0619
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=3.4.1 <4.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.6
  http: ^1.2.1
  geolocator: ^12.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^3.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
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:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  fonts:
     - family: gothic
       fonts:
         - asset: font/laundrygothic.ttf
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

name: flutter0619
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=3.4.1 <4.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.6
  http: ^1.2.1
  geolocator: ^12.0.0
  intl: ^0.19.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^3.0.0

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter packages.
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:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  fonts:
     - family: gothic
       fonts:
         - asset: font/laundrygothic.ttf
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

timer_builder: ^2.0.0

import 'package:flutter/material.dart';
import 'package:flutter0619/Weather/SampleWeather.dart';
import 'package:intl/intl.dart';
import 'package:timer_builder/timer_builder.dart';

class WeatherMain extends StatelessWidget {
  const WeatherMain({super.key, required this.w});

  final SampleWeather w;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.lightBlue[100],
        elevation: 0.0,
      ),
      body: Container(
          color: Colors.lightBlue[100],
          padding: EdgeInsets.all(12),
          child: Column(children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  w.name,
                  style: TextStyle(fontSize: 50, fontWeight: FontWeight.bold),
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Text(
                      '${w.main.temp}도', // 숫자는 int라 포맷팅을 해줘야 함!
                      style: TextStyle(fontSize: 35, color: Colors.red),
                    ),
                    // intl
                    // DataFormat("출력방법")
                    // y - 연도
                    // M - 월
                    // d - 일
                    // yy년 MM월 dd일 - 24년 06월 26일
                    // yyyy년 - 2024년
                    // Text('00년 00월 00일',style: TextStyle(fontSize: 20)),
                    Text(DateFormat('yy년 MM월 dd일').format(DateTime.now()),
                        style: TextStyle(fontSize: 16)),

                    // time_builder 라이브러리
                    TimerBuilder.periodic(Duration(seconds: 1),
                        builder: (context) {
                      return Text(DateFormat('HH:mm:ss').format(DateTime.now()),
                          style: TextStyle(fontSize: 18));
                      //Text('00시 00분',style: TextStyle(fontSize: 20))
                    })
                  ],
                ),
              ],
            ),
            SizedBox(
              height: 30,
            ),
            Container(
              width: double.infinity,
              height: 150,
              decoration: BoxDecoration(
                  color: Colors.white, borderRadius: BorderRadius.circular(5)),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Expanded(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Image.network(
                            'https://openweathermap.org/img/wn/${w.weather[0].icon}.png'),
                        // weather[] -> wheather이 리스트이기 때문 -> 결과값
                        //Icon(Icons.sunny),
                        Text(w.weather[0].main)
                        // String이기 때문에 포맷팅이 따로 필요하지 않음!
                      ],
                    ),
                  ),
                  Container(
                    width: 1,
                    height: double.infinity,
                    color: Colors.grey[300],
                    margin: EdgeInsets.all(24),
                  ),
                  Expanded(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(4.0),
                          child: Icon(
                            Icons.water_drop_outlined,
                            size: 40,
                          ),
                        ),
                        Text('${w.main.humidity}')
                      ],
                    ),
                  ),
                  Container(
                    width: 1,
                    height: double.infinity,
                    color: Colors.grey[300],
                    margin: EdgeInsets.all(24),
                  ),
                  Expanded(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Padding(
                          padding: const EdgeInsets.all(4.0),
                          child: Icon(
                            Icons.wind_power,
                            size: 40,
                          ),
                        ),
                        Text('${w.wind.speed}'),
                      ],
                    ),
                  ),
                ],
              ),
            )
          ])),
    );
  }
}
import 'package:flutter/material.dart';
import 'package:flutter0619/Weather/SampleWeather.dart';
import 'package:flutter0619/Weather/weather_main.dart';
import 'package:geolocator/geolocator.dart';
import 'package:http/http.dart';

// 위치 정보 파악
// 해당 위치에 맞는 날씨 가지고 오기

class LoadingPage extends StatelessWidget {
  const LoadingPage({super.key});

  @override
  Widget build(BuildContext context) {
    getLocation(context);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.lightBlue[100],
        elevation: 0.0, // AppBar가 떠 있는듯한 느낌을 줄 때 사용!
      ),
      body: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.lightBlue[100],
        child: Center(
          child: Container(
            child: CircularProgressIndicator(),
          ),
        ),
      ),
    );
  }
}

void getLocation(context) async {
  await Geolocator
      .requestPermission(); // requestPermission : 권한 설정 물어보는 코드 -> await가 꼭 필요!
  Position position = await Geolocator.getCurrentPosition();

  double lat = position.latitude;
  double lon = position.longitude;

  print("lat : $lat, lon : $lon");
  getWeather(lat, lon, context);
}

void getWeather(double lat, double lon, context) async {
  String url =
      "https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=5b7403969c39771b3a9b321993fe9666&units=metric";
  print(url);
  Response res = await get(Uri.parse(url));
  print(res.body);
  SampleWeather w1 = sampleWeatherFromJson(res.body);

  // 페이지 이동
  Navigator.push(
    context,
    MaterialPageRoute(builder: (_) => WeatherMain(w: w1)),
  );
  // Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) {
  //   return WeatherMain(
  //     w: w,
  //   );
  // }), (route) => false);
}
import 'package:flutter/material.dart';

import 'package:flutter0619/ex02_jsonParsing.dart';
import 'package:flutter0619/Weather/ex01_location.dart';
import 'package:flutter0619/Weather/ex02_sample_weather.dart';
import 'package:flutter0619/Weather/loading_page.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        fontFamily: "gothic",
      ),
      // home: ExJson(),
      // home: Location(),
      // home: ExWeather(),
      home: LoadingPage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // TRY THIS: Try changing the color here to a specific color (to
        // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
        // change color while the other colors stay the same.
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          //
          // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
          // action in the IDE, or press "p" in the console), to see the
          // wireframe for each widget.
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

'Flutter' 카테고리의 다른 글

ListView  (0) 2024.06.17
BottomPage  (0) 2024.06.17
ex33. Route  (0) 2024.06.14
ex32. Navigator  (0) 2024.06.14
ex31. Onboarding  (0) 2024.06.13