본문 바로가기
프로그래밍/Flutter

[Flutter] 14. 플러터 날씨 검색 화면 만들기

by 신나요 2022. 2. 28.

지난포스트에서 플러터 앱에서 openweather api 이용해서 날씨 정보를 얻어오는 방법 알아 보았고 플러터 앱에서 http get 해보았습니다. 이제 날씨 검색 화면을 만들어 보도록 하겠습니다.

 

다음 내용을 다루고 있습니다.

  1. 모델 클래스 만들기
  2. 다트 named constructor
  3. JSON문자열 객체로 변환(역 직렬화)
  4. 날씨 검색 화면 UI 만들기
  5. 위젯 반환 함수, Expanded 위젯 사용하기

모델(model) 클래스 만들기

OpenWeather API에서 날씨 화면에 필요한 데이터를 받아오고 있습니다.

다음 작업은 OpenWeather Api에서 가져온 JSON 데이터를 변환하여 사용자에게 나은 형식으로 제공하는 것입니다. JSON은 - 쌍으로 표현되는 텍스트 기반 형식입니다. 문자열을 프로젝트에서 쉽게 사용할 있는 객체로 변환해야 합니다.

모델 클래스를 생성해 보도록 하겠습니다. data 폴더에 weather.dart 라는 파일을 만들었고 아래와 같이 작성해 주었습니다.

날씨 모델 클래스

Weather라는 클래스를 만들었고, 날씨 정보 중 UI 사용자에게 보여주고 싶은 모든 필드를 선언했습니다. 호출될 모든 필드를 설정하는 생성자를 만들어야 합니다. Weather 클래스는 두개의 생성자를 가지고 있습니다. 번째 생성자는 Weather()입니다.

코드와 같이 다트에서는 this 키워드를 사용해서 매개변수로 전달한 값으로 생성자에서 필드를  자동으로 설정할 있습니다.

 

다트 Named Constructor

번째 생성자는 Weather.fromJson  Named Constructor 추가하고 있습니다.

Named Constructor

Dart에서는 "생성자명.임의명칭" 과 같이 기술하는 것으로  Named constructor라고 하는 복수의 생성자를 정의하는것이 가능합니다. 생성자 내에서 매개변수로 전달된 map객체 내부에의 값으로 클래스의 필드를 초기화 해주고 있습니다.

Weather 정보를 나타내는 모델클래스가 완성되었습니다. 이제 http 통신을 담당하는 http_helper 클래스에서 http get으로 가져온 데이터를 weather 객체를 생성하도록 수정하겠습니다.


Json 문자열 객체로 변환

다트(플러터)는 JSON문자열을 map객체로 변환하는 방법을 제공하고 있으며, 이는 다시 Weather 클래스의 인스턴스와 사용자 정의 객체로 쉽게 변환할 있습니다. dart:conver 라이브러리를 사용하면 JSON문자열을 map 객체로 자동 변환할 있습니다. 이러한 과정을 역 직렬화 라고 합니다. 객체 변환 라이브러리를 사용하기 위해서는 파일의 상단에 dart:convert를 import해야합니다.

dart:convert패키지를 import한 후에 getWeather메소드에서 json.decode 이용해 json문자열인 http.get의 리턴 값 resultmap으로 변환하였습니다.

json.decode 와 모델 클래스로 변환

map객체로 변환한 Weather.fromJson 생성자를 이용해 Weather 객체를 생성한 리턴하도록 수정하였습니다.

다음 스텝으로 getWeather 사용하는 weather_screen.dart에서 UI 추가하고, Weather 데이터를 ui 전달하여 화면에 출력해 보도록 하겠습니다.


날씨 검색 화면 UI 만들기

먼저 도시를 입력할 있는 텍스트 필드를 만들겠습니다.

(1)원래 있던 스캐폴드 body 내용을 삭제하였고 Padding 추가하였습니다. 패딩은 16픽셀의 EdgeInsets.all 사용하며 자식은 ListView 설정하였습니다. (2)ListView의 children 매개변수에서 다른 Padding 배치 하였습니다. (3)Padding의 자식으로 TextField 넣어주었고, TextEditingController txtPlace 넣어주었습니다. (4)decoration은 hintText suffixIcon 설정 하였습니다. (5)다시 suffixIcon IconButton위젯을 사용하여 버튼을 누를 때 실행할 onPressed 인수에 getWeatherData메소드와 연결시켜주었습니다.

텍스트 필드를 앱에서 살펴보면 아래와 같이 나오는걸 볼 있습니다.

IconButton위젯의 onPressed인수의 getWeatherData 메소드는 HttpHelper 클래스를 이용해 get통신을 하고 있습니다. getWeather의 매개변수로 TextEditingController인 txtPlace를 이용해 텍스트필드의 입력 값을 건네주고 있습니다.

돋보기 아이콘이 클릭했을 때 호출

이제 사용자가 도시를 입력 서치 아이콘(돋보기)을 클릭을 하면 getWeather가 호출되고, openweather api를 통해 날씨 데이터를 가져오게 됩니다.

 

UI 다음 단계로 ListView의 텍스트필드 아래에서 "온도: 값" 과 같은 라벨을 포함하는 위젯을 여러 개 배치하려고 합니다. 이러한 위젯과 스타일을 작성하고 필요에 따라 재사용할 있는 위젯을 반환하는 함수를 만들어 사용하도록 하겠습니다.

 

위젯 반환 함수 만들기

라벨과, 값을 인수로 받아, 두 개의 Text 위젯을 포함하는 위젯으로 반환하는 메서드를 만들어 보겠습니다.

위젯 반환 메소드

두 개의 Text 위젯 중에 첫 번째는 위젯은 라벨을 표현해주고, 번째는 위젯은 그 값을 표현하려고 합니다. 패딩에 포함된 Row위젯을 선언하였습니다. Row 위젯의 자식은 가로로 배치됩니다.

Expanded 위젯 사용법

사용 가능한 공간을 여러 부분으로 나누고 싶을 Row Column 안에서 Expanded 위젯을 사용할 있습니다. 첫 번째 Expanded flex 속성으로 3 설정하였고, 두 번째 Expanded flex 속성으로 4 설정하였습니다. Row flex가 3과 4 개의 Expanded 위젯이 포함되어 있으므로, 행의 사용 가능한 공간이 3 4 더한 7 부분으로 나뉘고, 번째 위젯은 7 3, 번째 위젯은 7 4 부분으로 공간이 나뉘게 됩니다.

Text위젯에서는 단순히 번째는 라벨의 텍스트를, 번째는 값을 넣어주고 있습니다.

 

row 위젯 작성 메소드가 완성 되었으니 이제 ListView에서 호출해 보도록 수정하겠습니다.

위젯을 반환하는 메소드인 weatherRow 호출하면서, 라벨 문자열과, 출력할 값을 매개변수로 건내주고 있습니다. weatherRow에서는 두개의 Text위젯을 포함한 위젯을 반환하게 될것입니다.

 

끝났습니다. 앱에서 확인해 보겠습니다.

에러 처리 등 아직 완벽하지 않지만, 기본 기능은 작동합니다!

 


여기까지 수고하셨습니다.
날씨 검색 화면을 만들면서 package, pubspec.yaml, http, get, async/await, JSON, Map, Model 등 여러 가지를알아보았습니다. 다음 포스트에는 데이터를 장치에 저장하는 방법에 대해 알아보도록 하겠습니다.  그리고 새로운 화면도 만들어야겠네요.

댓글