web-dev-qa-db-ja.com

関数(T)によってジェネリック型をフラッターで渡す

私は、ViewModelを子に容易にする汎用コンシューマーウィジェットを作成しようとしています。そのため、2つの機能があります。 1つはViewModelの初期化後にfunction(T)を持ち、もう1つはモデルをその子ウィジェットに渡すためのものです。

ジェネリッククラスのChangeNotifierの子であり、2つの関数でT値を送信するまで問題なく機能します。

その後、次のエラーが発生します。

タイプ '(OnBoardingViewModel)=> Null'はタイプ '(ChangeNotifier)=> void'のサブタイプではありません

そして

タイプ '(BuildContext、OnBoardingViewModel、Widget)=> Scaffold'はタイプ '(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(){

  }
}
3
quantum apps

なぜそうなのか正確にはわかりませんが、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,
      ),
    );
  }
}
0
Rene