Внедрение государственного управления провайдером. Помещение функции в create: свойство - PullRequest
0 голосов
/ 02 мая 2020

Я полностью потерян в области государственного управления. Перепробовал несколько учебников, статей, даже посмотрел на подобные проекты 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 голосов
/ 02 мая 2020

Есть несколько изменений, которые вы должны сделать, чтобы ваш код работал.

Изменить следующую строку

    child: ChangeNotifierProvider<WeatherModel>(

На

    child: ChangeNotifierProvider< ApiCall >(

Вы должны указать имя класса который расширяет ChangeNotifier.

Вы должны вызывать notifyListeners () в конце метода, для которого вы хотите изменить данные.

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

getWeather не должен возвращать никакого значения. Вместо этого вы можете создать любой объект WeatherModel в классе ApiCall, обновить его в этом методе и получить доступ к этому объекту, где бы вы ни хотели использовать эти данные.

Обновление:

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

Вы можете вызвать этот метод следующим образом.

Provider.of<ApiCall>(context).getWeather('New York');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...