728x90
반응형
Youtube 코딩셰프님의 강의를 요약 정리한 글이다. dart 언어나 이론 부분은 자바와 유사하여 대부분 제외하였고, flutter 기초 위주로 정리한다.
https://www.youtube.com/@codingchef
지난 글에 이어서 날씨 앱 만들기를 해본다. 중요한 개념들을 코드를 보며 살펴볼 것이다.
1. 객체지향적으로 짜기
아래와 같은 원칙을 갖고 코드를 짠다.
- 파일 이름은 소문자로만 구성한다. snake_case로 작성한다.
- 각 파일 및 클래스가 어떤 객체(명사)를 대표한다고 생각하고 이름을 짓는다. 예를 들어 my_location은 location을 얻어오는 역할을(역할만) 하고, 그 내부에 latitude, longitude라는 멤버 변수(속성)가 있다.
- my_location, network간 의존성이 없도록한다. 이 두 객체를 loading.dart에서 따로 불러와서 조합하는 방식으로 구성하면 각 객체의 독립성이 유지된다.
my_location.dart
geolocator의 예제 코드를 복사해와서 예외처리를 하는 부분은 생략했다. 살펴볼 부분은 다음과 같다.
- MyLocation이라는 클래스를 만들어 위치를 얻어올 수 있게 객체 지향적으로 바라봤고, latitude, longitude라는 속성값을 비동기로 넣어준다.
- double?로 ?를 사용하여 async/await 비동기로 받아오는 부분을 nullable 처리했다.
- try-catch 구문으로 getCurrentPosition이 실패했을 때 에러를 출력하도록 했다.
class MyLocation {
double? latitude;
double? longitude;
Future<void> getPosition() async {
bool serviceEnabled;
LocationPermission permission;
... 중략
try {
Position position = await Geolocator.getCurrentPosition();
latitude = position.latitude;
longitude = position.longitude;
} catch (e) {
print(e);
}
}
network.dart
외부 api와 연결하는 역할을 하는 객체를 만들기 위해 Network 클래스를 생성했다.
API 키값은 고정된 값이므로 const로 정의하고 class 바깥쪽에서 할당했다. url은 비동기작업 후 한번만 할당되면 끝이므로 final로 정의했다.
const String OpenWeatherApiKey = 'ad5123ac4......';
class Network {
final String openWeatherUrl;
Network(this.openWeatherUrl);
Future<dynamic> getParsedWeatherData() async {
var response = await http.get(Uri.parse(openWeatherUrl));
if(response.statusCode == 200) {
return jsonDecode(response.body);
}
}
}
2. flutter 데이터 전달 구조 이해하기
loading.dart
- State 클래스(_LoadingState) 내부에 메서드를 작성한다. 그래야 Navigator.push에서(또는 다른 메서드에서도) context를 불러올 수 있다.
- MyLocation class와 Network class를 독립적으로 불러와서 서로 의존하지 않도록 해준다.
- jsonDecode로 입력한 부분은 dynamic 타입으로 받았다.
- var, dynamic: 모두 정해진 자료형이 아니라 입력된 값으로 자료형을 추론한다. var는 한 번 어떤 타입의 데이터가 입력되면 다른 타입으로 재할당이 불가하고, dynamic은 재할당이 가능하다.
- WeatherScreen 클래스를 만들 때 속성값으로 weatherData를 넘겨주는 방식으로 만들었다. 이렇게 객체지향에서 객체 간 서로 데이터를 주고 받는 방식으로 코딩을 한다.
class Loading extends StatefulWidget {
const Loading({
super.key,
});
@override
State<Loading> createState() => _LoadingState();
}
class _LoadingState extends State<Loading> {
... 중략
void getData() async {
try {
MyLocation myLocation = MyLocation();
myLocation.getPosition();
double? latitude = myLocation.latitude;
double? longitude = myLocation.longitude;
final String url =
'https://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$OpenWeatherApiKey&units=metric';
Network network = Network(url);
dynamic parsedData = await network.getParsedWeatherData();
Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) {
return WeatherScreen(
weatherData: parsedData,
);
}));
} catch (e) {
print(e);
}
}
...
@override
Widget build(BuildContext context) {
...
ElevatedButton(
onPressed: () {
getData();
},
child: Text('Get My Location'),
style: ElevatedButton.styleFrom(backgroundColor: Colors.grey),
)
}
weather_screen.dart
loading.dart에서 받아온 데이터(weatherData: parsedData)를 dynamic 멤버 변수로 받아왔다. 생성자를 ({ }) 형태로 사용하여 named optional parameter로 두었다. WeatherScreen은 위젯이기 때문에 위젯을 불러올 때 key, weatherData라는 이름을 지정하여 불러올 수 있도록 이렇게 지정한다.
-initState가 실행된 후 build 메서드가 실행된다!
class WeatherScreen extends StatefulWidget {
dynamic weatherData;
WeatherScreen({Key? key, this.weatherData}) : super(key: key);
@override
State<WeatherScreen> createState() => _WeatherScreenState();
}
class _WeatherScreenState extends State<WeatherScreen> {
double? latitude;
double? longitude;
String? cityName;
@override
void initState() {
// super.initState();
var weatherData = widget.weatherData;
print(widget.weatherData);
latitude = weatherData['coord']['lat'];
longitude = weatherData['coord']['lon'];
cityName = weatherData['name'];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Row(
children: [
Column(
children: [
Text('$latitude')
],
)
],
),
);
}
}
728x90
반응형
'Programming-[CrossPlatform] > Flutter' 카테고리의 다른 글
Flutter 기본-14. 날씨 앱 만들기 데이터, 이미지 연동, Key 개념 이해하기 (0) | 2023.02.03 |
---|---|
Flutter 기본-13. 날씨 앱 만들기 기본3, UI 구성 실습 (0) | 2023.01.29 |
Flutter 기본-11. Null Safety, 날씨앱 만들기 기본 (0) | 2023.01.24 |
Flutter 기본-10. Dart 학습: final/const, List.generate, Future/Async, FutureBuilder (0) | 2023.01.24 |
Flutter 기본-9. 주사위 게임 페이지- Focus, Expanded, Random, showToast (0) | 2023.01.22 |