Хотите ли вы изучить Flutter или просто хотите создать проект для развлечения. Эта статья для вас❤️ Научитесь создавать приложение с погодой на Flutter!

Flutter — популярный фреймворк для создания мобильных приложений для платформ Android и iOS. С Flutter вы можете легко создавать красивые и высокопроизводительные мобильные приложения, используя единую кодовую базу. В этом уроке мы создадим простое погодное приложение, которое отображает текущие погодные условия для заданного местоположения.

Для начала давайте создадим новый проект Flutter, выполнив следующую команду в вашем терминале.

flutter create weather_app

Это создаст новый проект Flutter с именем weather_app.

Далее нам нужно добавить в наш проект пакет http. Этот пакет позволит нам делать HTTP-запросы к API OpenWeatherMap. Чтобы добавить этот пакет, просто добавьте следующую строку в файл pubspec.yaml вашего проекта:

dependencies:
  http: ^0.13.4

После добавления пакета запустите flutter pub get в своем терминале, чтобы загрузить и установить пакет.

Теперь давайте создадим новый класс Weather, который будет представлять погодные условия для данного местоположения. Этот класс будет иметь четыре свойства:

  • locationName: название локации
  • iconUrl: URL-адрес значка погоды для текущих условий.
  • temperature: текущая температура в градусах Цельсия.
  • description: краткое описание текущих условий

Вот как должен выглядеть класс Weather:

import ‘dart:convert’;
import 'package:http/http.dart' as http;

class Weather {
  final String locationName;
  final String iconUrl;
  final double temperature;
  final String description;

  Weather({
    required this.locationName,
    required this.iconUrl,
    required this.temperature,
    required this.description,
  });

  factory Weather.fromJson(Map<String, dynamic> json) {
    final weather = json['weather'][0];
    final main = json['main'];
    final iconCode = weather['icon'];
    final iconUrl = 'https://openweathermap.org/img/w/$iconCode.png';
    final temperature = main['temp'].toDouble();
    final description = weather['description'];
    final locationName = json['name'];
    return Weather(
      locationName: locationName,
      iconUrl: iconUrl,
      temperature: temperature,
      description: description,
    );
  }

  static Future<Weather> fetch(
      String apiKey, double latitude, double longitude) async {
    final url =
        'https://api.openweathermap.org/data/2.5/weather?lat=$latitude&lon=$longitude&appid=$apiKey&units=metric';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final json = jsonDecode(response.body);
      return Weather.fromJson(json);
    } else {
      throw Exception('Failed to load weather data');
    }
  }
}

Фабричный метод fromJson используется для создания нового объекта Weather из ответа JSON, возвращаемого API OpenWeatherMap. Мы извлекаем необходимые данные из объекта JSON и используем их для инициализации объекта Weather.

Метод fetch используется для выполнения HTTP-запроса к API OpenWeatherMap и возврата Future, содержащего объект Weather. Этот метод принимает ключ API, широту и долготу в качестве аргументов.

Теперь, когда у нас настроен класс Weather, давайте создадим новый виджет Flutter для отображения данных о погоде. Мы назовем этот виджет WeatherApp.

Для начала мы создадим новый виджет с состоянием под названием WeatherApp. Этот виджет будет содержать FutureBuilder, который будет отображать данные о погоде после их загрузки.

class WeatherApp extends StatefulWidget {
  const WeatherApp({Key? key}) : super(key: key);

  @override
  _WeatherAppState createState() => _WeatherAppState();
}

class _WeatherAppState extends State<WeatherApp> {
  late Future<Weather> _futureWeather;

  @override
  void initState() {
    super.initState();
    _futureWeather =
        Weather.fetch('your-api-key', 37.7749, -122.4194);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Weather App'),
        ),
        body: Center(
          child: FutureBuilder<Weather>(
            future: _futureWeather,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                final weather = snapshot.data!;
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(
                      '${weather.temperature}°C',
                      style: TextStyle(fontSize: 48),
                    ),
                    Image.network(weather.iconUrl),
                    Text(
                      weather.description,
                      style: TextStyle(fontSize: 24),
                    ),
                    Text(
                      weather.locationName,
                      style: TextStyle(fontSize: 24),
                    ),
                  ],
                );
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              return CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

Разберем этот код:

  • Мы определяем виджет с состоянием под названием WeatherApp.
  • В методе initState мы создаем Future, который извлекает данные о погоде, используя метод Weather.fetch, который мы определили ранее. Мы передаем наш ключ API, а также широту и долготу местоположения, для которого мы хотим получить данные о погоде.
  • В методе build мы создаем FutureBuilder, который будет отображать данные о погоде после их получения. FutureBuilder принимает _futureWeather Future, которые мы определили ранее, и функцию builder, которая будет вызываться при разрешении Future.
  • Если Future разрешается успешно и у нас есть данные о погоде, мы создаем Column, содержащий виджет Text, отображающий температуру, виджет Image, отображающий значок погоды, виджет Text, отображающий описание погоды, и виджет Text, отображающий название местоположения.
  • Если Future по какой-либо причине не работает, мы отображаем сообщение об ошибке с помощью виджета Text.
  • Если Future все еще разрешается, мы отображаем CircularProgressIndicator, чтобы указать, что данные извлекаются.

Теперь, когда у нас настроен виджет WeatherApp, мы можем добавить его в основной метод нашего приложения:

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: WeatherApp(),
    );
  }
}

Когда мы запустим наше приложение, мы должны увидеть данные о погоде в месте, указанном в виджете WeatherApp. Если мы хотим отобразить данные о погоде для другого местоположения, мы можем просто обновить значения широты и долготы в initState.

Еще один замечательный проект — получить широту и долготу из местоположения пользователя, но это для другого проекта. А пока запустите приложение, используя:

Flutter run

И посмотрите, работает ли это!

Спасибо, что прочитали статью «Создайте погодное приложение с помощью Flutter!» Я надеюсь, что этот урок помог вам создать красивое и функциональное погодное приложение. ☀️🌦️🌧️🌩️

Помните, что Flutter — это мощный инструмент для создания мобильных приложений, и при наличии необходимых навыков и знаний вы можете создавать потрясающие приложения как для iOS, так и для Android. ⚡

Не стесняйтесь продолжать исследовать и экспериментировать с Flutter и не стесняйтесь делиться своими творениями с сообществом. 🤝

Еще раз спасибо за чтение и удачного кодирования! 💻👨‍💻👩‍💻

Также специально для вас я оставил репозиторий на GitHub❤️

https://github.com/turboteun2/weather_app