Flutter提供程序错误:继承的窗口小部件更改时

时间:2020-06-17 10:44:34

标签: flutter dart flutter-dependencies provider flutter-change-notifier

我认为与供应商的关系不佳。什么是正确的代码?

**import 'package:flutter/material.dart';
import 'package:geo_app/model/wether.dart';**

class UpdateWeather extends ChangeNotifier{

WeatherModel weathers = WeatherModel();
int temperature;
dynamic weatherImage;
String city;
dynamic weatherBack;


Future<void> updateUi(dynamic weatherData) async {
double temp =await weatherData['main']['temp'].toDouble();
 temperature = temp.toInt();
 var condition =await weatherData['weather'][0]['id'];
weatherBack = weathers.getWBackgroundImage(condition);
weatherImage = weathers.getWeatherImage(condition);
city = weatherData['name'];
notifyListeners();
}
}

错误消息是这样的。

继承的窗口小部件发生更改时,例如,如果 Theme.of()更改,其依赖的小部件将重新构建。如果 从属窗口小部件对继承的窗口小部件的引用位于 构造函数或initState()方法,然后重新构建依赖项 小部件将不会反映继承的小部件中的更改。

通常,对继承的窗口小部件的引用应出现在窗口小部件中 build()方法。或者,基于继承进行初始化 窗口小部件可以放置在didChangeDependencies方法中,该方法是 在initState之后以及每当依赖项更改时调用 之后。

相关的引起错误的小部件是
MaterialApp
lib / main.dart:15
引发异常时,这就是堆栈

这是使用此提供程序的代码。

import 'package:flutter/material.dart';
import 'package:geo_app/Provider/update_wearher.dart';
import 'package:geo_app/const.dart';
import 'package:geo_app/model/wether.dart';
import 'package:geo_app/view/navigator_dawer.dart';
import 'package:provider/provider.dart';

class LocationScreen extends StatefulWidget {
static const routeName = '/lacation';

final locationWeather;

const LocationScreen({Key key, this.locationWeather}) : super(key: 
key);
@override
_LocationScreenState createState() => _LocationScreenState();
}

class _LocationScreenState extends State<LocationScreen> {
WeatherModel weathers = WeatherModel();

@override
void initState() {
 super.initState();
 Provider.of<UpdateWeather> 
(context).updateUi(widget.locationWeather);
}

@override
void setState(fn) {
Provider.of<UpdateWeather> 
(context).updateUi(widget.locationWeather);
super.setState(fn);
 }

@override
Widget build(BuildContext context) {

return Scaffold(
  body:Stack(children: <Widget>[
  Container(
      decoration: BoxDecoration(
        color: Colors.grey[850],
        image: DecorationImage(
            image: AssetImage(Provider.of<UpdateWeather> 
     (context).weatherBack),
            colorFilter:  ColorFilter.mode(
                Colors.black.withOpacity(0.5), BlendMode.dstATop),
            fit: BoxFit.cover),
      ),
      constraints: BoxConstraints.expand(),
      padding: EdgeInsets.only(top : 200),
      child: Column(children: <Widget>[
         Image.asset(Provider.of<UpdateWeather> 
    (context).weatherImage,
            height: 120,
          width:120,
        ),
        // Image.asset(
        //   'assets/sun.png',
        //   alignment: Alignment.center,
        //   height: 120,
        //   width:120,
        // ),  
        SizedBox(height:30),
        Text('${Provider.of<UpdateWeather>(context).temperature}°',
        style: ktextStyle,
        ),
        SizedBox(
          height:10
        ),
        Text('${Provider.of<UpdateWeather>(context).city}',
        style: ktextStyle,)
      ],
      ),
    ),
    Positioned(
      child:AppBar(
       actions: <Widget>[
         IconButton(icon: Icon(Icons.near_me),
          onPressed: () async {
            var weatherData = await weathers.getLocationWeather();
           Provider.of<UpdateWeather>(context). 
  updateUi(weatherData);
          })
       ],
    backgroundColor: Colors.transparent,
    elevation: 0,
  ),)
  ],
  ),
  drawer: Theme(child: NavigatorDrawer(),
    data: Theme.of(context).
    copyWith(canvasColor: Colors.blueGrey.withOpacity(0.2)),
  )
  );
 }
 }

1 个答案:

答案 0 :(得分:0)

对不起,我的回复很慢,但是我相信以下是您应该如何配置屏幕的方法。该错误来自以下事实:在UpdateWeather上方的小部件树中没有定义的提供程序LocationScreen,因此您需要使用ChangeNotifierProvider来定义一个提供程序。 (您也可以使用其他提供程序,但是通过查看UpdateWeather似乎很适合ChangeNotifierProvider。)然后您可以在提供程序下方添加类型Consumer的{​​{1}}并且在UpdateWeather中调用notifyListeners()时,它将自动重建屏幕。

请注意,在UpdateWeather的{​​{1}}调用中使用了..飞镖运算符,以确保在构建屏幕时调用create方法。这也使我们可以在提供者现在处理状态更改时使整个屏幕变为无状态。

另外,由于提供者是由ChangeNotifierProvider返回的,因此您还可以将所有updateUI引用替换为Provider.of<UpdateWeather>()

weather