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