반응형
도시 추가, 수정, 삭제 기능을 구현 했다.
city.dart
class City {
String name; // 도시 이름을 저장할 변수
City(this.name); // 생성자: 도시 이름을 받아서 초기화
}
String name; // 도시 이름을 저장할 변수
City(this.name); // 생성자: 도시 이름을 받아서 초기화
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
add_city_screen.dart
import 'package:flutter/material.dart';
class AddCityScreen extends StatefulWidget {
final Function(String) onAddCity; // 도시를 추가할 때 호출되는 콜백 함수
AddCityScreen({required this.onAddCity}); // 생성자: 콜백 함수를 받아서 초기화
@override
_AddCityScreenState createState() => _AddCityScreenState(); // 상태를 생성
}
class _AddCityScreenState extends State<AddCityScreen> {
final TextEditingController _controller = TextEditingController(); // 텍스트 필드 컨트롤러
void _handleAddCity() {
final cityName = _controller.text; // 텍스트 필드의 입력값을 가져옴
if (cityName.isNotEmpty) {
widget.onAddCity(cityName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 추가', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleAddCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('여길 눌러 도시 추가'), // 버튼 텍스트
),
],
),
),
);
}
}
class AddCityScreen extends StatefulWidget {
final Function(String) onAddCity; // 도시를 추가할 때 호출되는 콜백 함수
AddCityScreen({required this.onAddCity}); // 생성자: 콜백 함수를 받아서 초기화
@override
_AddCityScreenState createState() => _AddCityScreenState(); // 상태를 생성
}
class _AddCityScreenState extends State<AddCityScreen> {
final TextEditingController _controller = TextEditingController(); // 텍스트 필드 컨트롤러
void _handleAddCity() {
final cityName = _controller.text; // 텍스트 필드의 입력값을 가져옴
if (cityName.isNotEmpty) {
widget.onAddCity(cityName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 추가', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleAddCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('여길 눌러 도시 추가'), // 버튼 텍스트
),
],
),
),
);
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
city_detail_screen.dart
import 'package:flutter/material.dart';
class AddCityScreen extends StatefulWidget {
final Function(String) onAddCity; // 도시를 추가할 때 호출되는 콜백 함수
AddCityScreen({required this.onAddCity}); // 생성자: 콜백 함수를 받아서 초기화
@override
_AddCityScreenState createState() => _AddCityScreenState(); // 상태를 생성
}
class _AddCityScreenState extends State<AddCityScreen> {
final TextEditingController _controller = TextEditingController(); // 텍스트 필드 컨트롤러
void _handleAddCity() {
final cityName = _controller.text; // 텍스트 필드의 입력값을 가져옴
if (cityName.isNotEmpty) {
widget.onAddCity(cityName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 추가', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleAddCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('여길 눌러 도시 추가'), // 버튼 텍스트
),
],
),
),
);
}
}
class AddCityScreen extends StatefulWidget {
final Function(String) onAddCity; // 도시를 추가할 때 호출되는 콜백 함수
AddCityScreen({required this.onAddCity}); // 생성자: 콜백 함수를 받아서 초기화
@override
_AddCityScreenState createState() => _AddCityScreenState(); // 상태를 생성
}
class _AddCityScreenState extends State<AddCityScreen> {
final TextEditingController _controller = TextEditingController(); // 텍스트 필드 컨트롤러
void _handleAddCity() {
final cityName = _controller.text; // 텍스트 필드의 입력값을 가져옴
if (cityName.isNotEmpty) {
widget.onAddCity(cityName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 추가', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleAddCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('여길 눌러 도시 추가'), // 버튼 텍스트
),
],
),
),
);
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
city_list_screen.dart
import 'package:flutter/material.dart';
import 'city_detail_screen.dart';
import '../models/city.dart';
class CityListScreen extends StatelessWidget {
final List<City> cities; // 도시 목록
final Function(City) removeCity; // 도시 제거 콜백 함수
final Function(BuildContext, City) editCity; // 도시 수정 콜백 함수
CityListScreen({
required this.cities,
required this.removeCity,
required this.editCity,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('지금 날씨를 보자 !', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: ListView.builder(
itemCount: cities.length, // 도시 목록 길이
itemBuilder: (context, index) {
return ListTile(
title: Text(cities[index].name), // 도시 이름 표시
trailing: Row(
mainAxisSize: MainAxisSize.min, // 아이콘 버튼의 최소 크기 설정
children: [
IconButton(
icon: Icon(Icons.edit), // 수정 아이콘
onPressed: () {
editCity(context, cities[index]); // 수정 함수 호출
},
),
IconButton(
icon: Icon(Icons.delete), // 삭제 아이콘
onPressed: () {
removeCity(cities[index]); // 삭제 함수 호출
},
),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CityDetailScreen(city: cities[index]), // 상세 화면으로 이동
),
);
},
);
},
),
);
}
}
import 'city_detail_screen.dart';
import '../models/city.dart';
class CityListScreen extends StatelessWidget {
final List<City> cities; // 도시 목록
final Function(City) removeCity; // 도시 제거 콜백 함수
final Function(BuildContext, City) editCity; // 도시 수정 콜백 함수
CityListScreen({
required this.cities,
required this.removeCity,
required this.editCity,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('지금 날씨를 보자 !', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: ListView.builder(
itemCount: cities.length, // 도시 목록 길이
itemBuilder: (context, index) {
return ListTile(
title: Text(cities[index].name), // 도시 이름 표시
trailing: Row(
mainAxisSize: MainAxisSize.min, // 아이콘 버튼의 최소 크기 설정
children: [
IconButton(
icon: Icon(Icons.edit), // 수정 아이콘
onPressed: () {
editCity(context, cities[index]); // 수정 함수 호출
},
),
IconButton(
icon: Icon(Icons.delete), // 삭제 아이콘
onPressed: () {
removeCity(cities[index]); // 삭제 함수 호출
},
),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CityDetailScreen(city: cities[index]), // 상세 화면으로 이동
),
);
},
);
},
),
);
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
edit_city_screen.dart
import 'package:flutter/material.dart';
import '../models/city.dart';
class EditCityScreen extends StatefulWidget {
final City city; // 수정할 도시
final Function(City, String) onEditCity; // 도시 수정 콜백 함수
EditCityScreen({
required this.city,
required this.onEditCity,
});
@override
_EditCityScreenState createState() => _EditCityScreenState(); // 상태를 생성
}
class _EditCityScreenState extends State<EditCityScreen> {
late TextEditingController _controller; // 텍스트 필드 컨트롤러
@override
void initState() {
super.initState();
_controller = TextEditingController(text: widget.city.name); // 초기 텍스트 설정
}
void _handleEditCity() {
final newName = _controller.text; // 새 도시 이름을 가져옴
if (newName.isNotEmpty) {
widget.onEditCity(widget.city, newName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 수정', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleEditCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('Save Changes'), // 버튼 텍스트
),
],
),
),
);
}
}
import '../models/city.dart';
class EditCityScreen extends StatefulWidget {
final City city; // 수정할 도시
final Function(City, String) onEditCity; // 도시 수정 콜백 함수
EditCityScreen({
required this.city,
required this.onEditCity,
});
@override
_EditCityScreenState createState() => _EditCityScreenState(); // 상태를 생성
}
class _EditCityScreenState extends State<EditCityScreen> {
late TextEditingController _controller; // 텍스트 필드 컨트롤러
@override
void initState() {
super.initState();
_controller = TextEditingController(text: widget.city.name); // 초기 텍스트 설정
}
void _handleEditCity() {
final newName = _controller.text; // 새 도시 이름을 가져옴
if (newName.isNotEmpty) {
widget.onEditCity(widget.city, newName); // 콜백 함수 호출
Navigator.of(context).pop(); // 화면 종료
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('도시 수정', style: TextStyle(color: Colors.white)), // 앱바 제목
backgroundColor: Colors.lightBlue, // 앱바 배경색
),
body: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: Column(
children: [
TextField(
controller: _controller, // 텍스트 필드 컨트롤러 설정
decoration: InputDecoration(labelText: '도시 이름 : 정확한 영어 이름으로 입력'), // 텍스트 필드 데코레이션
),
SizedBox(height: 20), // 간격 추가
ElevatedButton(
onPressed: _handleEditCity, // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text('Save Changes'), // 버튼 텍스트
),
],
),
),
);
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
home_screen.dart
import 'package:flutter/material.dart';
import 'city_list_screen.dart';
import 'add_city_screen.dart';
import 'edit_city_screen.dart'; // EditCityScreen 클래스 가져오기
import '../models/city.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState(); // 상태를 생성
}
class _HomeScreenState extends State<HomeScreen> {
List<City> cities = [City('Seoul'), City('New York')]; // 초기 도시 목록
void _addCity(String name) {
setState(() {
cities.add(City(name)); // 도시 추가
});
}
void _removeCity(City city) {
setState(() {
cities.remove(city); // 도시 제거
});
}
void _editCity(City city, String newName) {
setState(() {
city.name = newName; // 도시 이름 수정
});
}
void _navigateToAddCityScreen(BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddCityScreen(onAddCity: _addCity), // 도시 추가 화면으로 이동
),
);
}
void _navigateToEditCityScreen(BuildContext context, City city) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditCityScreen(city: city, onEditCity: _editCity), // 도시 수정 화면으로 이동
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
CityListScreen(
cities: cities, // 도시 목록 전달
removeCity: _removeCity, // 도시 제거 함수 전달
editCity: _navigateToEditCityScreen, // 도시 수정 함수 전달
),
Align(
alignment: Alignment.bottomCenter, // 하단 가운데 정렬
child: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: SizedBox(
width: double.infinity,
height: 80, // 버튼의 높이를 조정
child: ElevatedButton(
onPressed: () => _navigateToAddCityScreen(context), // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text(
'도시 추가',
style: TextStyle(fontSize: 24), // 버튼 텍스트 크기 조정
),
),
),
),
),
],
),
);
}
}
import 'city_list_screen.dart';
import 'add_city_screen.dart';
import 'edit_city_screen.dart'; // EditCityScreen 클래스 가져오기
import '../models/city.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState(); // 상태를 생성
}
class _HomeScreenState extends State<HomeScreen> {
List<City> cities = [City('Seoul'), City('New York')]; // 초기 도시 목록
void _addCity(String name) {
setState(() {
cities.add(City(name)); // 도시 추가
});
}
void _removeCity(City city) {
setState(() {
cities.remove(city); // 도시 제거
});
}
void _editCity(City city, String newName) {
setState(() {
city.name = newName; // 도시 이름 수정
});
}
void _navigateToAddCityScreen(BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddCityScreen(onAddCity: _addCity), // 도시 추가 화면으로 이동
),
);
}
void _navigateToEditCityScreen(BuildContext context, City city) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditCityScreen(city: city, onEditCity: _editCity), // 도시 수정 화면으로 이동
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
CityListScreen(
cities: cities, // 도시 목록 전달
removeCity: _removeCity, // 도시 제거 함수 전달
editCity: _navigateToEditCityScreen, // 도시 수정 함수 전달
),
Align(
alignment: Alignment.bottomCenter, // 하단 가운데 정렬
child: Padding(
padding: const EdgeInsets.all(16.0), // 패딩 설정
child: SizedBox(
width: double.infinity,
height: 80, // 버튼의 높이를 조정
child: ElevatedButton(
onPressed: () => _navigateToAddCityScreen(context), // 버튼 클릭 시 호출 함수
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.lightBlue), // 버튼 배경색 설정
foregroundColor: MaterialStateProperty.all<Color>(Colors.white), // 버튼 글자색 설정
),
child: Text(
'도시 추가',
style: TextStyle(fontSize: 24), // 버튼 텍스트 크기 조정
),
),
),
),
),
],
),
);
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
weather_service.dart
import 'package:http/http.dart' as http; // http 패키지를 가져와서 http로 명명
import 'dart:convert'; // JSON 인코딩 및 디코딩을 위한 패키지
class WeatherService {
final String apiKey = '8f1aee2e4009fb6828780a625ee49123'; // OpenWeatherMap API 키
// 도시 이름을 받아 날씨 데이터를 가져오는 비동기 함수
Future<Map<String, dynamic>> fetchWeather(String city) async {
// API 요청을 위한 URL 생성
final response = await http.get(
Uri.parse('https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric'),
);
// HTTP 요청이 성공했는지 확인
if (response.statusCode == 200) {
return json.decode(response.body); // 성공 시, 응답 본문을 JSON 형식으로 디코딩하여 반환
} else {
throw Exception('Failed to load weather data'); // 실패 시, 예외 발생
}
}
}
import 'dart:convert'; // JSON 인코딩 및 디코딩을 위한 패키지
class WeatherService {
final String apiKey = '8f1aee2e4009fb6828780a625ee49123'; // OpenWeatherMap API 키
// 도시 이름을 받아 날씨 데이터를 가져오는 비동기 함수
Future<Map<String, dynamic>> fetchWeather(String city) async {
// API 요청을 위한 URL 생성
final response = await http.get(
Uri.parse('https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric'),
);
// HTTP 요청이 성공했는지 확인
if (response.statusCode == 200) {
return json.decode(response.body); // 성공 시, 응답 본문을 JSON 형식으로 디코딩하여 반환
} else {
throw Exception('Failed to load weather data'); // 실패 시, 예외 발생
}
}
}
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
main.dart
import 'package:flutter/material.dart'; // Flutter의 Material Design 위젯 가져오기
import 'screens/home_screen.dart'; // 홈 화면 위젯 가져오기
void main() {
runApp(MyApp()); // 앱 실행
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '지금 날씨를 보자!', // 앱 제목 설정
theme: ThemeData(
primarySwatch: Colors.blue, // 기본 테마 색상 설정
),
home: HomeScreen(), // 홈 화면 위젯 설정
);
}
}
import 'screens/home_screen.dart'; // 홈 화면 위젯 가져오기
void main() {
runApp(MyApp()); // 앱 실행
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '지금 날씨를 보자!', // 앱 제목 설정
theme: ThemeData(
primarySwatch: Colors.blue, // 기본 테마 색상 설정
),
home: HomeScreen(), // 홈 화면 위젯 설정
);
}
}
반응형
'앱' 카테고리의 다른 글
OpenWeather을 이용한 플러터 앱 (2) | 2024.06.12 |
---|