Flutter 시리즈 기사 - 실제 프로젝트

이 기사에서는 실용적인 Flutter 애플리케이션을 사용하여 데이터베이스 저장, HTTP 요청 수행 등 최근에 배운 지식을 종합적으로 적용해 보겠습니다. 우리는 사용자가 입력한 도시 이름에 따라 도시의 날씨 정보를 얻을 수 있고, 사용자가 쿼리한 도시 목록을 로컬 데이터베이스에 저장할 수 있는 간단한 날씨 애플리케이션을 개발할 것입니다.

1단계: 요구사항 분석 및 설계

1. 프로젝트 목표 파악

우리의 목표는 날씨 애플리케이션을 개발하는 것입니다. 사용자는 애플리케이션에 도시 이름을 입력한 다음 도시의 날씨 정보를 얻을 수 있습니다.

2. 디자인 인터페이스

우리 앱은 도시 이름을 입력하고 날씨 정보를 표시하는 메인 페이지와 사용자가 쿼리한 도시 목록을 표시하는 쿼리 기록 페이지의 두 페이지로 구성됩니다.

2단계: 개발

1. Flutter 프로젝트 만들기

먼저 명령줄에서 새 Flutter 프로젝트를 만듭니다.

flutter create my_first_flutter_app

그런 다음 프로젝트 디렉터리를 입력합니다.

cd my_first_flutter_app

2. 코딩 구현

a. 페이지 및 경로 생성

lib 폴더에 home_page.dart, History_page.dart라는 두 개의 파일을 만듭니다.

home_page.dart:

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

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String city = '';
  String weather = '';

  void getWeather() async {
    final response = await http.get(Uri.parse(
        'https://api.openweathermap.org/data/2.5/weather?q=$city&appid=YOUY_API_KEY'));

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      setState(() {
        weather =
            'Temperature: ${data['main']['temp']}°C, Weather: ${data['weather'][0]['main']}';
      });
    } else {
      setState(() {
        weather = 'Failed to get weather data';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Weather App'),
      ),
      body: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            TextField(
              onChanged: (value) {
                setState(() {
                  city = value;
                });
              },
              decoration: InputDecoration(labelText: 'City Name'),
            ),
            ElevatedButton(
              onPressed: () {
                getWeather();
              },
              child: Text('Get Weather'),
            ),
            SizedBox(height: 20),
            Text(
              weather,
              style: TextStyle(fontSize: 18),
            ),
          ],
        ),
      ),
    );
  }
}

역사_페이지.dart:

import 'package:flutter/material.dart';
import 'package:my_first_flutter_app/database_helper.dart';
import 'package:my_first_flutter_app/city.dart';

class HistoryPage extends StatefulWidget {
  @override
  _HistoryPageState createState() => _HistoryPageState();
}

class _HistoryPageState extends State<HistoryPage> {
  List<City> cities = [];

  @override
  void initState() {
    super.initState();
    fetchCities();
  }

  void fetchCities() async {
    final dbHelper = DatabaseHelper.instance;
    final allRows = await dbHelper.queryAllRows();
    setState(() {
      cities = allRows.map((row) => City.fromMap(row)).toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Search History'),
      ),
      body: ListView.builder(
        itemCount: cities.length,
        itemBuilder: (context, index) {
          final city = cities[index];
          return ListTile(
            title: Text(city.name),
            subtitle: Text('Weather: ${city.weather}'),
          );
        },
      ),
    );
  }
}

main.dart 파일에서 경로를 설정합니다:

import 'package:flutter/material.dart';
import 'package:my_first_flutter_app/home_page.dart';
import 'package:my_first_flutter_app/history_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/': (context) => HomePage(),
        '/history': (context) => HistoryPage(),
      },
    );
  }
}

b. 데이터베이스 기능 실현

우리는 SQLite를 사용하여 사용자가 쿼리하는 도시 목록을 저장합니다. 데이터베이스 생성 및 관리를 위해 lib 폴더에 city.dart, Database_helper.dart라는 새 파일을 생성합니다.

city.dart

class City {
  int id;
  String name;
  String weather;

  City({this.id = 0, required this.name, required this.weather});

  Map<String, dynamic> toMap() {
    return {'id': id, 'name': name, 'weather': weather};
  }

  City.fromMap(Map<String, dynamic> map)
      : id = map['id'],
        name = map['name'],
        weather = map['weather'];
}

데이터베이스_헬퍼.다트

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:my_first_flutter_app/city.dart';

class DatabaseHelper {
  static final _databaseName = 'weather_database.db';
  static final _databaseVersion = 1;

  static final table = 'cities';

  static final columnId = '_id';
  static final columnName = 'name';
  static final columnWeather = 'weather';

  DatabaseHelper._privateConstructor();
  static final DatabaseHelper instance = DatabaseHelper._privateConstructor();

  static Database? _database;
  Future<Database?> get database async {
    if (_database != null) return _database;
    _database = await _initDatabase();
    return _database;
  }

  _initDatabase() async {
    String path = join(await getDatabasesPath(), _databaseName);
    return await openDatabase(path,
        version: _databaseVersion, onCreate: _onCreate);
  }

  Future<void> _onCreate(Database db, int version) async {
    await db.execute('''
          CREATE TABLE $table (
            $columnId INTEGER PRIMARY KEY,
            $columnName TEXT NOT NULL,
            $columnWeather TEXT NOT NULL
          )
          ''');
  }

  Future<int> insert(City city) async {
    Database? db = await instance.database;
    return await db?.insert(table, city.toMap()) ?? 0;
  }

  Future<List<Map<String, dynamic>>> queryAllRows() async {
    Database? db = await instance.database;
    return await db?.query(table) ?? [];
  }
}

3단계: 테스트

1. 애플리케이션 실행

다음 명령을 사용하여 에뮬레이터 또는 실제 장치에서 앱을 실행합니다.

flutter run

앱이 예상대로 작동하는지 확인하고 도시의 날씨를 쿼리하고 쿼리 기록을 볼 수 있는지 확인하세요.

2. 단위 테스트 및 통합 테스트 수행

수동 테스트 외에도 단위 테스트 및 통합 테스트를 수행하여 애플리케이션의 안정성과 정확성을 보장해야 합니다. Flutter에서는 테스트를 위해 flutter_test 패키지를 사용할 수 있습니다.

4단계: 게시

개발과 테스트가 끝나면 애플리케이션 출시를 고려할 수 있습니다. 게시하기 전에 다음 단계를 완료해야 합니다.

1. APK 또는 IPA 파일 생성

다음 명령을 사용하여 APK 파일(Android) 또는 IPA 파일(iOS)을 생성합니다.

flutter build apk
flutter build ios

2. 개발자 계정 신청

애플리케이션 스토어(예: Google Play 또는 App Store)에 게시하려면 개발자 계정을 신청하고 해당 게시 지침을 따라야 합니다.

3. 신청서 제출

APK 또는 IPA 파일을 준비하고 개발자 계정을 신청한 후에는 검토 및 출시를 위해 적절한 앱 스토어에 앱을 제출할 수 있습니다.

요약하다

이 기사에서는 데이터베이스 저장, HTTP 요청 수행 등을 포함하여 최근에 배운 내용을 간단한 날씨 애플리케이션 예제와 결합했습니다. 이 실습 프로젝트를 통해 Flutter 애플리케이션의 개발 프로세스에 대해 더 깊이 이해하고 실제 프로젝트에서 공통 기술과 모범 사례를 마스터할 수 있습니다.

이 실용적인 프로젝트가 당신에게 도움이 되기를 바랍니다. 질문이 있거나 추가 안내가 필요한 경우 언제든지 저에게 문의해 주세요. Flutter 개발 여정에 행운이 있기를 바랍니다!

추천

출처blog.csdn.net/xudepeng0813/article/details/132159843