在 flutter 中通过 Function(T) 传递泛型
passing generic type by Function(T) in flutter
我正在尝试创建一个通用的消费者小部件,以促进 ViewModel 到其子项。因此我有两个功能。一个在 ViewModel 初始化之后有一个函数 (T),另一个用于将模型传递给它的子 Widget。
在通用 class 中是 ChangeNotifier 的子项,在我想在两个函数中发送 T 值之前它工作正常。
然后我得到以下错误:
type '(OnBoardingViewModel) => Null' is not a subtype of type
'(ChangeNotifier) => void'
和
type '(BuildContext, OnBoardingViewModel, Widget) => Scaffold' is not
a subtype of type
'(BuildContext, ChangeNotifier, Widget) => Widget'
但是当我将扩展类型从 ChangeNotifier 更改为 OnBoardingViewModel 时,一切正常。
有人可以帮助我或者解释为什么这不起作用吗??
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:provider/provider.dart';
class StateFullConsumerWidget<T extends ChangeNotifier> extends StatefulWidget{
StateFullConsumerWidget({@required this.builder,Key key,this.onPostViewModelInit,this.child}) : super(key : key);
final Widget Function(BuildContext context, ChangeNotifier value, Widget child) builder;
final Widget child;
final void Function(T) onPostViewModelInit;
@override
_StateFullConsumerWidgetState<T> createState() => _StateFullConsumerWidgetState<T>();
}
class _StateFullConsumerWidgetState<T extends ChangeNotifier> extends State<StateFullConsumerWidget>{
T _viewModel;
@override
void initState() {
// assign the model once when state is initialised
_viewModel = GetIt.instance.get<T>();
widget.onPostViewModelInit(_viewModel);
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
builder: (context) => _viewModel,
child: Consumer<T>(
builder: widget.builder,
child: widget.child,
),
);
}
}
我的插件
StateFullConsumerWidget<OnBoardingViewModel>(
onPostViewModelInit: (viewModel){
buildIntroList(viewModel);
viewModel.maxPages = _introWidgetsList.length;
},
builder: (context,viewModel,child) {
return Scaffold(
key: widget.scaffoldKey,
body: SafeArea(
child: Container(),
),
),
);
},
);
我的视图模型
import 'package:flutter/material.dart';
class OnBoardingViewModel extends ChangeNotifier{
OnBoardingViewModel(){
}
}
我不太确定为什么会这样,但 dart 编译器无法将 StateFullConsumerWidget 中的类型 T 识别为与 _StateFullConsumerWidgetState 相同的类型 T。如果将函数传递给 State,一切都会按预期进行。
结果代码:
class StateFullConsumerWidget<T extends ChangeNotifier> extends StatefulWidget{
StateFullConsumerWidget({@required this.builder,Key key,this.onPostViewModelInit,this.child}) : super(key : key);
final Widget Function(BuildContext context, T value, Widget child) builder;
final Widget child;
final Function(T viewModel) onPostViewModelInit;
@override
_StateFullConsumerWidgetState<T> createState() => _StateFullConsumerWidgetState<T>(onPostViewModelInit, builder);
}
class _StateFullConsumerWidgetState<T extends ChangeNotifier> extends State<StateFullConsumerWidget>{
final Function(T viewModel) _onPostViewModelInit;
final Widget Function(BuildContext context, T value, Widget child) _builder;
T _viewModel;
_StateFullConsumerWidgetState(this._onPostViewModelInit, this._builder);
@override
void initState() {
// assign the model once when state is initialised
_viewModel = GetIt.instance.get<T>();
_onPostViewModelInit(_viewModel);
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
builder: (context) => _viewModel,
child: Consumer<T>(
builder: _builder,
child: widget.child,
),
);
}
}
您使用通用类型 T
的方式不完整。在您的代码中 StateFullConsumerWidget
和 _StateFullConsumerWidgetState
classes 之间的关系是 StateFullConsumerWidget
使用与自身相同的 T
类型参数创建其状态,因此小部件知道状态使用与它相同的通用类型。但是,从 _StateFullConsumerWidgetState
的角度来看,class 是这样声明的:
class _StateFullConsumerWidgetState<T extends ChangeNotifier>
extends State<StateFullConsumerWidget>
问题是状态 class 使用的是 StateFullConsumerWidget
的一般形式,因此 _StateFullConsumerWidgetState
正在接收的 T
之间没有明确的关系类型参数和 StateFullConsumerWidget
正在使用的 T
。 Dart 不知道如何调和这种不明确的关系,因此它默认使用类型约束允许的最小公分母,即 ChangeNotifier
.
因此,当您尝试将 T
视为 OnBoardingViewModel
时,Dart 会抛出错误,因为就状态 class 而言,T
父小部件的是 ChangeNotifier
,而不是 OnBoardingViewModel
。
您可以通过在声明状态时传递类型参数来解决此问题 class:
class _StateFullConsumerWidgetState<T extends ChangeNotifier>
extends State<StateFullConsumerWidget<T>>
我正在尝试创建一个通用的消费者小部件,以促进 ViewModel 到其子项。因此我有两个功能。一个在 ViewModel 初始化之后有一个函数 (T),另一个用于将模型传递给它的子 Widget。
在通用 class 中是 ChangeNotifier 的子项,在我想在两个函数中发送 T 值之前它工作正常。
然后我得到以下错误:
type '(OnBoardingViewModel) => Null' is not a subtype of type '(ChangeNotifier) => void'
和
type '(BuildContext, OnBoardingViewModel, Widget) => Scaffold' is not a subtype of type '(BuildContext, ChangeNotifier, Widget) => Widget'
但是当我将扩展类型从 ChangeNotifier 更改为 OnBoardingViewModel 时,一切正常。
有人可以帮助我或者解释为什么这不起作用吗??
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:provider/provider.dart';
class StateFullConsumerWidget<T extends ChangeNotifier> extends StatefulWidget{
StateFullConsumerWidget({@required this.builder,Key key,this.onPostViewModelInit,this.child}) : super(key : key);
final Widget Function(BuildContext context, ChangeNotifier value, Widget child) builder;
final Widget child;
final void Function(T) onPostViewModelInit;
@override
_StateFullConsumerWidgetState<T> createState() => _StateFullConsumerWidgetState<T>();
}
class _StateFullConsumerWidgetState<T extends ChangeNotifier> extends State<StateFullConsumerWidget>{
T _viewModel;
@override
void initState() {
// assign the model once when state is initialised
_viewModel = GetIt.instance.get<T>();
widget.onPostViewModelInit(_viewModel);
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
builder: (context) => _viewModel,
child: Consumer<T>(
builder: widget.builder,
child: widget.child,
),
);
}
}
我的插件
StateFullConsumerWidget<OnBoardingViewModel>(
onPostViewModelInit: (viewModel){
buildIntroList(viewModel);
viewModel.maxPages = _introWidgetsList.length;
},
builder: (context,viewModel,child) {
return Scaffold(
key: widget.scaffoldKey,
body: SafeArea(
child: Container(),
),
),
);
},
);
我的视图模型
import 'package:flutter/material.dart';
class OnBoardingViewModel extends ChangeNotifier{
OnBoardingViewModel(){
}
}
我不太确定为什么会这样,但 dart 编译器无法将 StateFullConsumerWidget 中的类型 T 识别为与 _StateFullConsumerWidgetState 相同的类型 T。如果将函数传递给 State,一切都会按预期进行。
结果代码:
class StateFullConsumerWidget<T extends ChangeNotifier> extends StatefulWidget{
StateFullConsumerWidget({@required this.builder,Key key,this.onPostViewModelInit,this.child}) : super(key : key);
final Widget Function(BuildContext context, T value, Widget child) builder;
final Widget child;
final Function(T viewModel) onPostViewModelInit;
@override
_StateFullConsumerWidgetState<T> createState() => _StateFullConsumerWidgetState<T>(onPostViewModelInit, builder);
}
class _StateFullConsumerWidgetState<T extends ChangeNotifier> extends State<StateFullConsumerWidget>{
final Function(T viewModel) _onPostViewModelInit;
final Widget Function(BuildContext context, T value, Widget child) _builder;
T _viewModel;
_StateFullConsumerWidgetState(this._onPostViewModelInit, this._builder);
@override
void initState() {
// assign the model once when state is initialised
_viewModel = GetIt.instance.get<T>();
_onPostViewModelInit(_viewModel);
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
builder: (context) => _viewModel,
child: Consumer<T>(
builder: _builder,
child: widget.child,
),
);
}
}
您使用通用类型 T
的方式不完整。在您的代码中 StateFullConsumerWidget
和 _StateFullConsumerWidgetState
classes 之间的关系是 StateFullConsumerWidget
使用与自身相同的 T
类型参数创建其状态,因此小部件知道状态使用与它相同的通用类型。但是,从 _StateFullConsumerWidgetState
的角度来看,class 是这样声明的:
class _StateFullConsumerWidgetState<T extends ChangeNotifier>
extends State<StateFullConsumerWidget>
问题是状态 class 使用的是 StateFullConsumerWidget
的一般形式,因此 _StateFullConsumerWidgetState
正在接收的 T
之间没有明确的关系类型参数和 StateFullConsumerWidget
正在使用的 T
。 Dart 不知道如何调和这种不明确的关系,因此它默认使用类型约束允许的最小公分母,即 ChangeNotifier
.
因此,当您尝试将 T
视为 OnBoardingViewModel
时,Dart 会抛出错误,因为就状态 class 而言,T
父小部件的是 ChangeNotifier
,而不是 OnBoardingViewModel
。
您可以通过在声明状态时传递类型参数来解决此问题 class:
class _StateFullConsumerWidgetState<T extends ChangeNotifier>
extends State<StateFullConsumerWidget<T>>