一尘不染

在Flutter中通过Function(T)传递泛型类型

flutter

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

泛型类中的ChangeChangeifier的子级,并且可以正常工作,直到我想在两个函数中发送T值为止。

然后我得到以下错误:

类型’(OnBoardingViewModel)=> Null’不是类型’(ChangeNotifier)=> void’的子类型

类型’(BuildContext,OnBoardingViewModel,Widget)=>脚手架’不是类型’(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(),
            ),
          ),
        );
      },
    );

我的ViewModel

import 'package:flutter/material.dart';

class OnBoardingViewModel extends ChangeNotifier{

  OnBoardingViewModel(){

  }
}

阅读 1899

收藏
2020-08-13

共1个答案

一尘不染

您使用通用类型的方式T是不完整的。您的代码中编写StateFullConsumerWidget_StateFullConsumerWidgetState类与类之间的关系StateFullConsumerWidget可以使用与T自身相同的类型参数来创建其状态,因此小部件知道该状态使用与该类型相同的通用类型。从的角度来看_StateFullConsumerWidgetState,该类是这样声明的:

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

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

因此,当您尝试将T视为时OnBoardingViewModel,Dart会引发错误,因为据状态类所知,T父窗口小部件的为ChangeNotifier,而不是OnBoardingViewModel

您可以通过在声明状态类时传递type参数来解决此问题:

class _StateFullConsumerWidgetState<T extends ChangeNotifier> 
    extends State<StateFullConsumerWidget<T>>
2020-08-13