Flutter提供者错误。当继承的小部件改变

问题描述 投票:0回答:1

我觉得我和供应商打交道不是很好。正确的代码是什么?

**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();
}
}

错误信息是这样的。

当继承的widget发生变化时,例如如果Theme.of()的值发生变化,其依赖的widget会被重建。如果依赖的widget对继承的widget的引用是在构造函数或initState()方法中,那么重建的依赖的widget将不会反映继承的widget的变化。

通常,对继承的小组件的引用应该发生在小组件构建()方法中。另外,基于继承的widget的初始化可以放在didChangeDependencies方法中,该方法在initState之后以及此后每当依赖关系发生变化时都会被调用。

相关的导致错误的widget是MaterialApp libmain.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)),
  )
  );
 }
 }
flutter dart flutter-dependencies provider flutter-change-notifier
1个回答
0
投票

对不起,我的回复很慢,但我相信以下是你应该如何构建你的屏幕。这个错误是由于没有定义一个叫作 UpdateWeather 上的小部件树中 LocationScreen 所以你需要用 ChangeNotifierProvider. (您也可以使用其他供应商,但通过查看 UpdateWeather 感觉 ChangeNotifierProvider 是一个很好的选择)。) 然后你可以添加一个 Consumer 类型 UpdateWeather 下面的提供者,它将自动重建屏幕,当 notifyListeners() 所谓 UpdateWeather.

请注意飞镖的使用 .. 经营者中 create 召唤 ChangeNotifierProvider 这确保了 updateUI 方法在屏幕构建时被调用。这也允许我们使整个屏幕无状态,因为提供者现在处理状态的变化。

此外,你也可以替换所有的 Provider.of<UpdateWeather>() 参考文献有 weather 作为提供者被返回的 Consumer<UpdateWeather>.

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 StatelessWidget {
  static const routeName = '/lacation';
  final locationWeather;
  final WeatherModel weathers = WeatherModel();

  LocationScreen({Key key, this.locationWeather});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<UpdateWeather>(
      create: (context) => UpdateWeather()..updateUi(locationWeather),
      child: Consumer<UpdateWeather>(
        builder: (context, weather, _) => Scaffold(
            body: Stack(
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                    color: Colors.grey[850],
                    image: DecorationImage(
                        image: AssetImage(weather.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(
                        weather.weatherImage,
                        height: 120,
                        width: 120,
                      ),
                      // Image.asset(
                      //   'assets/sun.png',
                      //   alignment: Alignment.center,
                      //   height: 120,
                      //   width:120,
                      // ),
                      SizedBox(height: 30),
                      Text(
                        '${weather.temperature}°',
                        style: ktextStyle,
                      ),
                      SizedBox(height: 10),
                      Text(
                        '${weather.city}',
                        style: ktextStyle,
                      )
                    ],
                  ),
                ),
                Positioned(
                  child: AppBar(
                    actions: <Widget>[
                      IconButton(
                          icon: Icon(Icons.near_me),
                          onPressed: () async {
                            var weatherData =
                                await weathers.getLocationWeather();
                            weather.updateUi(weatherData);
                          })
                    ],
                    backgroundColor: Colors.transparent,
                    elevation: 0,
                  ),
                )
              ],
            ),
            drawer: Theme(
              child: NavigatorDrawer(),
              data: Theme.of(context)
                  .copyWith(canvasColor: Colors.blueGrey.withOpacity(0.2)),
            )),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.