【问题标题】:Provider State Management implementation. Putting a function in create: property提供者状态管理实施。将函数放入 create: property
【发布时间】:2020-05-02 15:46:23
【问题描述】:

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

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 在创建时应该只接收一个对象,而我正在向它传递一个函数。但我不知道还能在哪里调用该 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,
  });
}

【问题讨论】:

  • 可以添加模型和ApiCall类吗?
  • 完成。看看

标签: flutter dart


【解决方案1】:

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

更改以下行

    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');

【讨论】:

  • child: ChangeNotifierProvider( create: (context) => ApiCall().getWeather('New York'), 我应该在哪里调用 getWeather?仍然不能这样工作,因为 getWeather 是现在无效。我还添加了这一行:final appState = Provider.of(context); 所以我应该转到 Text 小部件并将其设置为 appState.weatherModel.temp 例如。但我无法进入天气模型在 getWeather 函数中填充(但未返回)。
猜你喜欢
  • 2020-01-15
  • 2020-05-23
  • 2020-06-15
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 2014-10-27
  • 2021-12-13
  • 1970-01-01
相关资源
最近更新 更多