免责声明::我知道有几个类似的问题,但是没有一个问题可以帮助我了解此特定情况下的问题。
我创建了一个接受ChangeNotifier
的实用程序小部件,并在数据更改时自动重建该小部件。
此小部件的代码略有缩短,但是可见的问题却是可见的:
class ChangeNotifierConsumer<T extends ChangeNotifier> extends StatefulWidget {
const ChangeNotifierConsumer({
Key key,
@required this.notifier,
@required this.builder,
}) : super(key: key);
final T notifier;
final Widget Function(BuildContext context, T cache) builder;
@override
_ChangeNotifierConsumerState createState() => _ChangeNotifierConsumerState();
}
class _ChangeNotifierConsumerState extends State<ChangeNotifierConsumer> {
@override
Widget build(BuildContext context) => widget.builder(context, widget.notifier);
}
class Model extends ChangeNotifier { ... }
然后我将按以下方式使用小部件,但这就是发生错误的地方:
ChangeNotifierConsumer<Model>(
notifier: Model(),
builder: (BuildContext context, Model model) { ... }
)
确切的错误消息是:
type '(BuildContext, Model) => ListView' is not a subtype of type '(BuildContext, ChangeNotifier) => Widget'
dart分析也没有编译时错误或输出,仅在运行时失败。
尽管模型扩展了ChangeNotifier,为什么仍会发生此错误?
如果我按以下方式使用构建器,则没有问题:
builder: (BuildContext context, dynamic model) {
Model model = model as Model;
}
答案 0 :(得分:0)
Imho在扩展ChangeNotifier的方法中存在一个小错误。
在OOP中扩展表示“是”。 例如,狮子扩展动物=>狮子是动物。
在您的情况下,通过扩展ChangeNotifier,您基本上可以说:
模型是一个ChangeNotifier,不是这种情况。如果我错了请纠正我。
我很想弄清楚类型问题,但不知道为什么会这样。 同时,我编写了一个示例,将“保存”并按预期工作。
完整的示例:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TestModel _model = TestModel(
'id', 'name'
);
_changeValue(){
_model.setId('newId');
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(56.0),
child: ChangeNotifierConsumer<TestModel>(
model: _model,
builder: (BuildContext context) {
return Column(
children: <Widget>[
Text(_model.id),
RaisedButton(
child: Text(_model.name),
onPressed: _changeValue,
)
],
);
},
)), Text(_model.id)
],
)
)
);
}
}
class ChangeNotifierConsumer<T extends Model> extends StatefulWidget {
ChangeNotifierConsumer({
Key key,
@required this.model,
@required this.builder,
}) : super(key: key);
final T model;
final Widget Function(BuildContext context) builder;
@override
_ChangeNotifierConsumerState createState() => _ChangeNotifierConsumerState();
}
class _ChangeNotifierConsumerState extends State<ChangeNotifierConsumer> {
@override
void initState() {
super.initState();
widget.model.addListener(_listener);
}
@override
void dispose() {
widget.model.removeListener(_listener);
super.dispose();
}
void _listener() {
print('setstate');
setState(() {});
}
@override
Widget build(BuildContext context) => widget.builder(context);
}
abstract class Model with ChangeNotifier {
}
class TestModel extends Model {
String _id;
String _name;
TestModel(this._id, this._name);
get id => _id;
get name => _name;
setId(String id) {
_id = id;
notifyListeners();
}
}