generics - 在 flutter 中通过 Function(T) 传递泛型类型

标签 generics flutter dart flutter-widget

我正在尝试创建一个通用的消费者小部件,以方便其子项的 ViewModel。因此我有两个功能。一个在 ViewModel 初始化之后有一个函数(T),另一个用于将模型传递给它的子 Widget。

在泛型类中是 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(),
            ),
          ),
        );
      },
    );

我的 View 模型
import 'package:flutter/material.dart';

class OnBoardingViewModel extends ChangeNotifier{

  OnBoardingViewModel(){

  }
}

最佳答案

您使用泛型类型的方式 T不完整。 StateFullConsumerWidget之间的关系和 _StateFullConsumerWidgetState在您的代码中编写的类是这样的 StateFullConsumerWidget使用相同的 T 创建它的状态type 参数作为它自己,所以小部件知道状态使用与它相同的通用类型。从_StateFullConsumerWidgetState的角度来看,但是,类是这样声明的:

class _StateFullConsumerWidgetState<T extends ChangeNotifier> 
    extends State<StateFullConsumerWidget>

问题是状态类使用了 StateFullConsumerWidget 的一般形式,所以 T 之间没有明确的关系那个_StateFullConsumerWidgetState正在接收作为类型参数和 T那个StateFullConsumerWidget正在使用。 Dart 不知道如何协调这种模棱两可的关系,因此它默认使用类型约束允许的最小公分母,即 ChangeNotifier .

正因为如此,当你试图治疗 TOnBoardingViewModel , Dart 抛出错误,因为据状态类所知,T父小部件的名称是 ChangeNotifier ,不是 OnBoardingViewModel .

您可以通过在声明状态类时传递类型参数来解决此问题:
class _StateFullConsumerWidgetState<T extends ChangeNotifier> 
    extends State<StateFullConsumerWidget<T>>

关于generics - 在 flutter 中通过 Function(T) 传递泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57886661/

相关文章:

ios - Swift 3 Generic 无法转换 UITableViewCell 类型的值

firebase - Flutter:从 Firestore 延迟加载数据

flutter - Flutter-在PageView中传递数据

linq - 如何将LINQ查询结果转换为列表并返回通用列表?

java - 为什么 varargs (Class<? extends Throwable>... t) "unchecked or unsafe"操作?

java - 不了解 MapReduce NPE

flutter - 嵌套 ListView、StreamBuilder 和子集合

list - 如何在 flutter 中将字符串列表转换为字符串?

flutter - 使用 ScaffoldMessenger 显示自定义小部件

Dart:如何在我的自定义 Polymer 元素文件中解析编码