提供者状态管理的实施。将函数放在create:属性中

时间:2020-05-02 15:46:23

标签: flutter dart

我在州管理领域完全迷失了。尝试了多个教程,文章,甚至查看了Github的类似项目。不知道如何在我的Weather应用中实现提供商。

class WeatherMainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: kBackgroundColor,
      child: SafeArea(
        child: ChangeNotifierProvider<WeatherModel>(
          create: (context) => ApiCall().getWeather('New York'),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Container(
                margin: EdgeInsets.only(
                  bottom: 30,
                  top: 15,
                  left: 30,
                  right: 30,
                ),
                child: Column(
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          'Today 28. apr',
                          style: TextStyle(
                            color: kAccentColor,
                            fontSize: 18,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.end,
                          children: <Widget>[
                            MenuSearchButton(
                              boxSize: 60,
                              onPressed: () => print('search prssed'),
                              content: Icon(
                                Icons.search,
                                color: Colors.white,
                                size: 30,
                              ),
                            ),
                            MenuSearchButton(
                              boxSize: 60,
                              onPressed: () => print('menu pressed'),
                              content: Icon(
                                Icons.menu,
                                color: Colors.white,
                                size: 30,
                              ),
                            ),
                          ],
                        ),
                      ],
                    ),
                    Container(
                      padding: EdgeInsets.symmetric(vertical: 20.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: <Widget>[
                          Text(
                            '12',
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 100,
                            ),
                          ),
                          Container(
                            padding: EdgeInsets.only(left: 10.0),
                            child: Row(
                              children: <Widget>[
                                Icon(
                                  Icons.cloud,
                                  color: Colors.white,
                                  size: 25.0,
                                ),
                                SizedBox(width: 15.0),
                                Text(
                                  'Raining',
                                  style: TextStyle(
                                    color: Colors.white,
                                    fontSize: 18,
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
              Column(
                children: <Widget>[
                  Container(
                    margin: EdgeInsets.only(
                      bottom: 30,
                      top: 15,
                      left: 60,
                      right: 60,
                    ),
                    child: Text(
                      'Put on your coat, and don\'t forget the umbrella.',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 25,
                      ),
                    ),
                  ),
                  Divider(
                    color: kAccentColor,
                  ),
                  Container(
                    margin: EdgeInsets.only(
                      bottom: 30,
                      top: 15,
                      left: 30,
                      right: 30,
                    ),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: <Widget>[
                        DetailedCard(
                          header: 'HUMIDITY',
                          headerColor: kAccentColor,
                          text: '87%',
                          textColor: Colors.white,
                        ),
                        DetailedCard(
                          header: 'WIND M/S',
                          headerColor: kAccentColor,
                          text: '4,1',
                          textColor: Colors.white,
                        ),
                        DetailedCard(
                          header: 'FEELS LIKE',
                          headerColor: kAccentColor,
                          text: '18',
                          textColor: Colors.white,
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

所以我有一个模型类WeatherModel,它基本上是空的,仅包含天气信息的构造函数。 ApiCall类是所有联网的地方,它返回填充了数据的WeatherModel对象。但是使用这样的ChangeNotifier我得到了错误: “返回类型'Future'不是由匿名闭包定义的'WeatherModel'。

我读到ChangeNotifierProvider应该在创建时只接收一个Object,而我正在传递给它一个函数。但是我不知道该在哪里调用getWeather函数?完全迷路了。

编辑:

ApiCall.dart

class ApiCall extends ChangeNotifier{
  Future<WeatherModel> getWeather(String cityName) async {
    String url =
        'https://api.openweathermap.org/data/2.5/weather?q=$cityName&appid=$apikey';
    http.Response response = await http.get(url);

    if (response.statusCode == 200) {
      var weatherData = jsonDecode(response.body);

      return WeatherModel(
        temp: weatherData['main']['temp'] - 273.15,
        feelsLike: weatherData['main']['temp'] - 273.15,
        condition: weatherData['weather'][0]['main'],
        humidity: weatherData['main']['humidity'],
        windSpeed: weatherData['wind']['speed'],
      );
    } else {
      throw Exception('Ooops something went wrong');
    }
  }
}

WeatherModel.dart

class WeatherModel{
  final double temp;
  final double windSpeed;
  final int feelsLike;
  final int humidity;
  final String condition;

  WeatherModel({
    this.temp,
    this.windSpeed,
    this.feelsLike,
    this.humidity,
    this.condition,
  });
}

1 个答案:

答案 0 :(得分:0)

您应该对代码进行一些更改。

更改下一行

    child: ChangeNotifierProvider<WeatherModel>(

收件人

    child: ChangeNotifierProvider< ApiCall >(

您必须提供扩展ChangeNotifier的类名。

您必须在方法末尾调用notifyListeners(),要在其上更改数据。

  else {
      throw Exception('Ooops something went wrong');
    }
    notifyListeners();  // added line
  }

getWeather不应返回任何值。取而代之的是,您可以在ApiCall类中创建任何WeatherModel对象,并在该方法中对其进行更新,并在想要使用该数据的任何位置访问该对象。

更新:

 child: ChangeNotifierProvider<ApiCalll>( create: (context) => ApiCall()

您可以通过以下方式调用此方法。

Provider.of<ApiCall>(context).getWeather('New York');