简体   繁体   中英

How to get weather information in a local widget without calling api repeatedly as widget rebuilds in flutter?

I've a local widget WeatherCard which calls weather.getWeather() inside initState. getWeather() uses open weather map's API key to get the current weather under the hood. How can I get the weather data without calling the API repeatedly every time the WeatherCard is rebuild. I want to save the weather data results as soon as I get them, till the app is killed, so as to save my API calls.

weather_card.dart

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:intl/intl.dart';
import 'package:ambur/app_content/models/weather.dart';
import 'package:ambur/constants.dart';

class WeatherCard extends StatefulWidget {
  @override
  _WeatherCardState createState() => _WeatherCardState();
}

class _WeatherCardState extends State<WeatherCard> {
  final String dayDate = DateFormat('EEEE, d MMM').format(DateTime.now());
  WeatherModel weather = WeatherModel();
  String city;
  double temp;
  Icon weatherIcon;

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

  void updateUI() async {
    var weatherData = await weather.getWeather();

    setState(() {
      temp = weatherData['main']['temp'];
      city = weatherData['name'];
      print(city);
      var condition = weatherData['weather'][0]['id'];
      weatherIcon = weather.getWeatherIcon(condition);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      margin: const EdgeInsets.symmetric(horizontal: 10),
      padding: const EdgeInsets.symmetric(
        horizontal: 20,
        vertical: 15,
      ),
      decoration: BoxDecoration(
        color: Colors.red[100],
        borderRadius: BorderRadius.circular(20),
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Icon(Icons.location_on),
                      city == null
                          ? SpinKitRipple(
                              color: Colors.white,
                            )
                          : Text(
                              '$city',
                              style: kSellerLocationTextStyle,
                            ),
                    ],
                  ),
                  SizedBox(height: 10),
                  Text(
                    "$dayDate",
                    style: kDateTextStyle.copyWith(fontSize: 15),
                  ),
                  temp == null
                      ? SpinKitRipple(
                          color: Colors.white,
                        )
                      : Text(
                          '$temp °C',
                          style: kTempTextStyle,
                        ),
                ],
              ),
              weatherIcon == null
                  ? SpinKitRipple(
                      color: Colors.white,
                    )
                  : weatherIcon
            ],
          ),
          const Divider(),
          const SizedBox(height: 10),
          const Text(
            'Today is good day for weeding.',
            style: kLoginSubHeadingTextStyle,
          )
        ],
      ),
    );
  }
}

I've a local widget WeatherCard which calls weather.getWeather() inside initState. getWeather() uses open weather map's API key to get the current weather under the hood. How can I get the weather data without calling the API repeatedly every time the WeatherCard is rebuild. I want to save the weather data results as soon as I get them, till the app is killed, so as to save my API calls.

weather_card.dart

import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:intl/intl.dart';
import 'package:ambur/app_content/models/weather.dart';
import 'package:ambur/constants.dart';

class WeatherCard extends StatefulWidget {
  @override
  _WeatherCardState createState() => _WeatherCardState();
}

class _WeatherCardState extends State<WeatherCard> {
  final String dayDate = DateFormat('EEEE, d MMM').format(DateTime.now());
  WeatherModel weather = WeatherModel();
  String city;
  double temp;
  Icon weatherIcon;

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

  void updateUI() async {
    var weatherData = await weather.getWeather();

    setState(() {
      temp = weatherData['main']['temp'];
      city = weatherData['name'];
      print(city);
      var condition = weatherData['weather'][0]['id'];
      weatherIcon = weather.getWeatherIcon(condition);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.infinity,
      margin: const EdgeInsets.symmetric(horizontal: 10),
      padding: const EdgeInsets.symmetric(
        horizontal: 20,
        vertical: 15,
      ),
      decoration: BoxDecoration(
        color: Colors.red[100],
        borderRadius: BorderRadius.circular(20),
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Icon(Icons.location_on),
                      city == null
                          ? SpinKitRipple(
                              color: Colors.white,
                            )
                          : Text(
                              '$city',
                              style: kSellerLocationTextStyle,
                            ),
                    ],
                  ),
                  SizedBox(height: 10),
                  Text(
                    "$dayDate",
                    style: kDateTextStyle.copyWith(fontSize: 15),
                  ),
                  temp == null
                      ? SpinKitRipple(
                          color: Colors.white,
                        )
                      : Text(
                          '$temp °C',
                          style: kTempTextStyle,
                        ),
                ],
              ),
              weatherIcon == null
                  ? SpinKitRipple(
                      color: Colors.white,
                    )
                  : weatherIcon
            ],
          ),
          const Divider(),
          const SizedBox(height: 10),
          const Text(
            'Today is good day for weeding.',
            style: kLoginSubHeadingTextStyle,
          )
        ],
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM