Future
2024. 6. 18. 12:56ㆍFlutter
✅ 학습 목표
✅ 동기방식과 비동기방식
✅ 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 |