Flutter天气信息获取插件weather的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter天气信息获取插件weather的使用

简介

weather 插件使用 OpenWeatherMAP API 来获取当前天气状态和天气预报。你可以通过提供地理位置或城市名称来获取天气信息。

pub package

安装 (Flutter)

pubspec.yaml 文件中添加 weather 作为依赖项。有关如何添加依赖项的帮助,请参阅 pubspec 文档

dependencies:
  weather: ^latest_version

权限

此包本身不需要任何权限,但如果你需要获取设备的地理位置,建议使用 geolocator 插件。

使用

获取API密钥

首先,你需要一个来自 OpenWeatherMap 的 API 密钥,可以在 这里 免费获取。

创建 WeatherFactory 实例

使用 API 密钥创建 WeatherFactory 实例。你还可以指定语言(例如丹麦语):

import 'package:weather/weather.dart';

WeatherFactory wf = new WeatherFactory("YOUR_API_KEY");
// 或者指定语言
WeatherFactory wf = new WeatherFactory("YOUR_API_KEY", language: Language.DANISH);

当前天气

可以通过经纬度或城市名称查询当前天气:

double lat = 55.0111;
double lon = 15.0569;
String cityName = 'Kongens Lyngby';
WeatherFactory wf = WeatherFactory(key);

// 通过地理位置
Weather w = await wf.currentWeatherByLocation(lat, lon);

// 通过城市名称
Weather w = await wf.currentWeatherByCityName(cityName);

示例输出

Place Name: Kongens Lyngby [DK] (55.77, 12.5)
Date: 2020-07-13 17:17:34.000
Weather: Clouds, broken clouds
Temp: 17.1 Celsius, Temp (min): 16.7 Celsius, Temp (max): 18.0 Celsius,  Temp (feels like): 13.4 Celsius
Sunrise: 2020-07-13 04:43:53.000, Sunset: 2020-07-13 21:47:15.000
Weather Condition code: 803

温度单位

Temperature 类可以输出温度的不同单位:

double celsius = w.temperature.celsius;
double fahrenheit = w.temperature.fahrenheit;
double kelvin = w.temperature.kelvin;

五天天气预报

可以通过经纬度或城市名称获取五天天气预报:

// 通过地理位置
List<Weather> forecast = await wf.fiveDayForecastByLocation(lat, lon);

// 通过城市名称
List<Weather> forecast = await wf.fiveDayForecastByCityName(cityName);

异常处理

以下情况会抛出异常:

  • 提供的 OpenWeather API 密钥无效
  • API 返回错误响应(可能是API宕机)

AndroidX支持

仅适用于Android API级别28

更新 android/gradle.properties 文件内容:

android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M

android/build.gradle 文件中添加以下依赖项:

dependencies {
  classpath 'com.android.tools.build:gradle:3.3.0'
  classpath 'com.google.gms:google-services:4.2.0'
}

android/app/build.gradle 文件中设置编译和最小SDK版本:

compileSdkVersion 28
minSdkVersion 21

支持的语言

以下是支持的语言列表:

  • AFRIKAANS
  • ALBANIAN
  • ARABIC
  • AZERBAIJANI
  • BULGARIAN
  • CATALAN
  • CZECH
  • DANISH
  • GERMAN
  • GREEK
  • ENGLISH
  • BASQUE
  • PERSIAN
  • FARSI
  • FINNISH
  • FRENCH
  • GALICIAN
  • HEBREW
  • HINDI
  • CROATIAN
  • HUNGARIAN
  • INDONESIAN
  • ITALIAN
  • JAPANESE
  • KOREAN
  • LATVIAN
  • LITHUANIAN
  • MACEDONIAN
  • NORWEGIAN
  • DUTCH
  • POLISH
  • PORTUGUESE
  • PORTUGUESE_BRAZIL
  • ROMANIAN
  • RUSSIAN
  • SWEDISH
  • SLOVAK
  • SLOVENIAN
  • SPANISH
  • SERBIAN
  • THAI
  • TURKISH
  • UKRAINIAN
  • VIETNAMESE
  • CHINESE_SIMPLIFIED
  • CHINESE_TRADITIONAL
  • ZULU

示例代码

以下是一个完整的示例应用程序,展示了如何使用 weather 插件获取当前天气和五天天气预报:

import 'package:flutter/material.dart';
import 'package:weather/weather.dart';

enum AppState { NOT_DOWNLOADED, DOWNLOADING, FINISHED_DOWNLOADING }

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String key = 'YOUR_API_KEY';
  late WeatherFactory ws;
  List<Weather> _data = [];
  AppState _state = AppState.NOT_DOWNLOADED;
  double? lat, lon;

  @override
  void initState() {
    super.initState();
    ws = new WeatherFactory(key);
  }

  void queryForecast() async {
    FocusScope.of(context).requestFocus(FocusNode());
    setState(() {
      _state = AppState.DOWNLOADING;
    });

    List<Weather> forecasts = await ws.fiveDayForecastByLocation(lat!, lon!);
    setState(() {
      _data = forecasts;
      _state = AppState.FINISHED_DOWNLOADING;
    });
  }

  void queryWeather() async {
    FocusScope.of(context).requestFocus(FocusNode());

    setState(() {
      _state = AppState.DOWNLOADING;
    });

    Weather weather = await ws.currentWeatherByLocation(lat!, lon!);
    setState(() {
      _data = [weather];
      _state = AppState.FINISHED_DOWNLOADING;
    });
  }

  Widget contentFinishedDownload() {
    return Center(
      child: ListView.separated(
        itemCount: _data.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(_data[index].toString()),
          );
        },
        separatorBuilder: (context, index) {
          return Divider();
        },
      ),
    );
  }

  Widget contentDownloading() {
    return Container(
      margin: EdgeInsets.all(25),
      child: Column(children: [
        Text(
          'Fetching Weather...',
          style: TextStyle(fontSize: 20),
        ),
        Container(
            margin: EdgeInsets.only(top: 50),
            child: Center(child: CircularProgressIndicator(strokeWidth: 10)))
      ]),
    );
  }

  Widget contentNotDownloaded() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            'Press the button to download the Weather forecast',
          ),
        ],
      ),
    );
  }

  Widget _resultView() => _state == AppState.FINISHED_DOWNLOADING
      ? contentFinishedDownload()
      : _state == AppState.DOWNLOADING
          ? contentDownloading()
          : contentNotDownloaded();

  void _saveLat(String input) {
    lat = double.tryParse(input);
    print(lat);
  }

  void _saveLon(String input) {
    lon = double.tryParse(input);
    print(lon);
  }

  Widget _coordinateInputs() {
    return Row(
      children: <Widget>[
        Expanded(
          child: Container(
              margin: EdgeInsets.all(5),
              child: TextField(
                  decoration: InputDecoration(
                      border: OutlineInputBorder(), hintText: 'Enter latitude'),
                  keyboardType: TextInputType.number,
                  onChanged: _saveLat,
                  onSubmitted: _saveLat)),
        ),
        Expanded(
            child: Container(
                margin: EdgeInsets.all(5),
                child: TextField(
                    decoration: InputDecoration(
                        border: OutlineInputBorder(),
                        hintText: 'Enter longitude'),
                    keyboardType: TextInputType.number,
                    onChanged: _saveLon,
                    onSubmitted: _saveLon)))
      ],
    );
  }

  Widget _buttons() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Container(
          margin: EdgeInsets.all(5),
          child: TextButton(
            child: Text(
              'Fetch weather',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: queryWeather,
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue)),
          ),
        ),
        Container(
          margin: EdgeInsets.all(5),
          child: TextButton(
            child: Text(
              'Fetch forecast',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: queryForecast,
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Colors.blue)),
          ),
        )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Weather Example App'),
        ),
        body: Column(
          children: <Widget>[
            _coordinateInputs(),
            _buttons(),
            Text(
              'Output:',
              style: TextStyle(fontSize: 20),
            ),
            Divider(
              height: 20.0,
              thickness: 2.0,
            ),
            Expanded(child: _resultView())
          ],
        ),
      ),
    );
  }
}

这个示例应用程序允许用户输入经纬度并获取当前天气和五天天气预报。希望这个指南对你有所帮助!如果有任何问题,欢迎随时提问。


更多关于Flutter天气信息获取插件weather的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter天气信息获取插件weather的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个使用Flutter中的weather插件来获取天气信息的示例代码。这个示例假设你已经有一个Flutter项目,并且已经添加了weather插件作为依赖项。

首先,确保在pubspec.yaml文件中添加weather插件依赖:

dependencies:
  flutter:
    sdk: flutter
  weather: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

接下来,在你的Dart文件中使用weather插件来获取天气信息。以下是一个完整的示例,展示如何在Flutter应用中获取并显示天气信息。

import 'package:flutter/material.dart';
import 'package:weather/weather.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Weather App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatefulWidget {
  @override
  _WeatherScreenState createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  String _location = 'Beijing'; // 默认城市
  WeatherData? _weatherData;

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

  Future<void> _fetchWeatherData() async {
    try {
      // 假设你有一个API Key,这里需要替换为你的实际API Key
      String apiKey = '你的API_KEY';
      WeatherClient weatherClient = WeatherClient(apiKey: apiKey);

      // 获取当前天气信息
      WeatherResponse response = await weatherClient.getCurrentWeatherByCityName(_location);
      if (response.code == 200) {
        setState(() {
          _weatherData = response.data;
        });
      } else {
        print('Error fetching weather data: ${response.message}');
      }
    } catch (e) {
      print('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Weather Information'),
      ),
      body: Center(
        child: _weatherData == null
            ? CircularProgressIndicator()
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(
                    'City: ${_weatherData!.location!.name}',
                    style: TextStyle(fontSize: 24),
                  ),
                  SizedBox(height: 10),
                  Text(
                    'Temperature: ${_weatherData!.current!.temperature!.celsius.toString()}°C',
                    style: TextStyle(fontSize: 24, color: Colors.blue),
                  ),
                  SizedBox(height: 10),
                  Text(
                    'Weather: ${_weatherData!.current!.weather![0].description}',
                    style: TextStyle(fontSize: 18),
                  ),
                ],
              ),
      ),
    );
  }
}

// 假设WeatherData和WeatherResponse是从weather插件中获取的模型类
// 这些类通常会自动生成,如果你使用的是自动代码生成工具(如json_serializable)
// 以下只是示例,实际类结构可能会有所不同
class WeatherData {
  Location? location;
  Current? current;

  // 其他字段...
}

class Location {
  String? name;

  // 其他字段...
}

class Current {
  double? temperature;
  List<Weather>? weather;

  // 其他字段...
}

class Weather {
  String? description;

  // 其他字段...
}

class WeatherResponse {
  int code;
  String? message;
  WeatherData? data;
}

注意

  1. 上面的WeatherDataLocationCurrentWeather类是基于假设的,实际使用时你需要参考weather插件提供的实际数据模型。
  2. 你需要一个API Key来访问天气数据API。这个API Key通常在你注册天气信息API服务时会提供。
  3. 示例中的WeatherClientgetCurrentWeatherByCityName方法也是假设的,你需要根据weather插件的实际API来使用正确的方法和类。

确保你阅读并遵循weather插件的文档,以获取最新的API信息和用法。

回到顶部