Flutter 颤振:使用泛型创建小部件时出现子类型错误
我正在为我的应用程序使用viewmodels来扩展ChangeNotifier。为了使用它们,我尝试实现一个通用的基本小部件:Flutter 颤振:使用泛型创建小部件时出现子类型错误,flutter,flutter-provider,flutter-change-notifier,Flutter,Flutter Provider,Flutter Change Notifier,我正在为我的应用程序使用viewmodels来扩展ChangeNotifier。为了使用它们,我尝试实现一个通用的基本小部件: 类BasePageWidget 扩展StatefulWidget{ 最终函数(ViewModelType vm)初始化; 最终小部件功能(BuildContext上下文、ViewModelType vm)生成器; 最终视图模型类型_vm=sl.get(); BasePageWidget({Key-Key,this.init,this.builder}):super(K
类BasePageWidget
扩展StatefulWidget{
最终函数(ViewModelType vm)初始化;
最终小部件功能(BuildContext上下文、ViewModelType vm)生成器;
最终视图模型类型_vm=sl.get();
BasePageWidget({Key-Key,this.init,this.builder}):super(Key:Key);
@凌驾
_BasePageWidgetState createState()=>\u BasePageWidgetState();
}
类_BasePageWidgetState
扩展状态{
@凌驾
小部件构建(构建上下文){
返回ChangeNotifierProvider.value(
值:widget.\u vm,
儿童:消费者(
builder:(context,widget.vm,child)=>widget.builder(context,widget.vm),
),
);
}
@凌驾
void initState(){
if(widget.init!=null){
widget.init(widget.\u vm);
}
super.initState();
}
}
基本小部件有一个类型参数,并使用get_it包的服务定位器获取viewmodel的实例
但是当我尝试运行应用程序时,当使用小部件时:
void main() {
setup();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: BasePageWidget<ViewModel>(
init: (vm) => vm.setTitle("Set init State"),
builder: (context, vm) => FlatButton(
onPressed: () {
vm.setTitle("State2");
},
child: Text(vm.text),
),
),
);
}
}
这些错误似乎是由函数参数引起的:
final Function(ViewModelType vm) init;
final Widget Function(BuildContext context, ViewModelType vm) builder;
当我将泛型类型(ViewModelType)与dynamic交换时,应用程序运行良好(当然没有类型安全):
你知道如何使用通用参数运行它吗
下面是我的视图模型:
class ViewModel extends ChangeNotifier {
String text = '';
void setTitle(String text) {
this.text = text;
notifyListeners();
}
}
以及get_it设置:
GetIt sl = GetIt.instance;
Future<void> setup() async {
sl.registerFactory(() => ViewModel());
}
GetIt sl=GetIt.instance;
Future setup()异步{
sl.registerFactory(()=>ViewModel());
}
您可以复制粘贴运行下面的完整代码请将
状态
更改为状态
从
class\u BasePageWidgetState
扩展状态{
到
class\u BasePageWidgetState
扩展状态{
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:get_it/get_it.dart';
class BasePageWidget<ViewModelType extends ChangeNotifier>
extends StatefulWidget {
final Function(ViewModelType vm) init;
final Widget Function(BuildContext context, ViewModelType vm) builder;
final ViewModelType _vm = sl.get<ViewModelType>();
BasePageWidget({Key key, this.init, this.builder}) : super(key: key);
@override
_BasePageWidgetState createState() => _BasePageWidgetState<ViewModelType>();
}
class _BasePageWidgetState<ViewModelType extends ChangeNotifier>
extends State<BasePageWidget<ViewModelType>> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ViewModelType>.value(
value: widget._vm,
child: Consumer<ViewModelType>(
builder: (context, _vm, child) => widget.builder(context, widget._vm),
),
);
}
@override
void initState() {
if (widget.init != null) {
widget.init(widget._vm);
}
super.initState();
}
}
class ViewModel extends ChangeNotifier {
String text = '';
void setTitle(String text) {
this.text = text;
notifyListeners();
}
}
GetIt sl = GetIt.instance;
Future<void> setup() async {
sl.registerFactory(() => ViewModel());
}
void main() {
setup();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: BasePageWidget<ViewModel>(
init: (vm) => vm.setTitle("Set init State"),
builder: (context, vm) => Scaffold(
body: Center(
child: FlatButton(
onPressed: () {
vm.setTitle("State2");
},
child: Text(vm.text),
),
),
),
),
);
}
}
导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
导入“package:get_it/get_it.dart”;
类BasePageWidget
扩展StatefulWidget{
最终函数(ViewModelType vm)初始化;
最终小部件功能(BuildContext上下文、ViewModelType vm)生成器;
最终视图模型类型_vm=sl.get();
BasePageWidget({Key-Key,this.init,this.builder}):super(Key:Key);
@凌驾
_BasePageWidgetState createState()=>\u BasePageWidgetState();
}
类_BasePageWidgetState
扩展状态{
@凌驾
小部件构建(构建上下文){
返回ChangeNotifierProvider.value(
值:widget.\u vm,
儿童:消费者(
builder:(context,widget.vm,child)=>widget.builder(context,widget.vm),
),
);
}
@凌驾
void initState(){
if(widget.init!=null){
widget.init(widget.\u vm);
}
super.initState();
}
}
类ViewModel扩展了ChangeNotifier{
字符串文本=“”;
void setTitle(字符串文本){
this.text=文本;
notifyListeners();
}
}
GetIt sl=GetIt.instance;
Future setup()异步{
sl.registerFactory(()=>ViewModel());
}
void main(){
设置();
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主页:BasePageWidget(
init:(vm)=>vm.setTitle(“设置初始化状态”),
生成器:(上下文,vm)=>Scaffold(
正文:中(
孩子:扁平按钮(
已按下:(){
vm.setTitle(“State2”);
},
子项:文本(vm.Text),
),
),
),
),
);
}
}
GetIt sl = GetIt.instance;
Future<void> setup() async {
sl.registerFactory(() => ViewModel());
}
class _BasePageWidgetState<ViewModelType extends ChangeNotifier>
extends State<BasePageWidget> {
class _BasePageWidgetState<ViewModelType extends ChangeNotifier>
extends State<BasePageWidget<ViewModelType>> {
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:get_it/get_it.dart';
class BasePageWidget<ViewModelType extends ChangeNotifier>
extends StatefulWidget {
final Function(ViewModelType vm) init;
final Widget Function(BuildContext context, ViewModelType vm) builder;
final ViewModelType _vm = sl.get<ViewModelType>();
BasePageWidget({Key key, this.init, this.builder}) : super(key: key);
@override
_BasePageWidgetState createState() => _BasePageWidgetState<ViewModelType>();
}
class _BasePageWidgetState<ViewModelType extends ChangeNotifier>
extends State<BasePageWidget<ViewModelType>> {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ViewModelType>.value(
value: widget._vm,
child: Consumer<ViewModelType>(
builder: (context, _vm, child) => widget.builder(context, widget._vm),
),
);
}
@override
void initState() {
if (widget.init != null) {
widget.init(widget._vm);
}
super.initState();
}
}
class ViewModel extends ChangeNotifier {
String text = '';
void setTitle(String text) {
this.text = text;
notifyListeners();
}
}
GetIt sl = GetIt.instance;
Future<void> setup() async {
sl.registerFactory(() => ViewModel());
}
void main() {
setup();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: BasePageWidget<ViewModel>(
init: (vm) => vm.setTitle("Set init State"),
builder: (context, vm) => Scaffold(
body: Center(
child: FlatButton(
onPressed: () {
vm.setTitle("State2");
},
child: Text(vm.text),
),
),
),
),
);
}
}