最近開発を行っているときに、次の問題が発生しました。
TabController が initState メソッドで初期化された後、ネットワーク データを要求してデータを取得し、タブの数を再割り当てする必要があります。
_tabController = TabController(vsync: this, length: tabs.length);
setState メソッドの後でエラーが発生した後に TabController を再初期化する方法。
Flutter では、setState メソッドを使用して Widget を更新すると、Widget の状態は更新されますが、TabController は再初期化されません。TabController を再初期化する場合は、新しい TabController オブジェクトを作成し、それを setState メソッドで TabBarView に割り当てます。
サンプルコード:
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(
icon: Icon(Icons.directions_car),
text: 'Car',
),
Tab(
icon: Icon(Icons.directions_transit),
text: 'Transit',
),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
// Your Widgets
// Your Widgets
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_tabController.dispose();
_tabController = TabController(length: 2, vsync: this);
});
},
child: Icon(Icons.refresh),
),
);
}
}
复制代码
このサンプル コードでは、setState メソッドで TabController オブジェクトを再初期化しました。フローティング ボタンをクリックすると、setState メソッドが呼び出され、TabController オブジェクトが再初期化され、TabBarView が新しい TabController オブジェクトで更新されます。
上記のコードを実行すると、まだエラーが発生していることがわかり、ここに問題があることがわかります。
SingleTickerProviderStateMixin は TickerProvider として 1 回のみ使用できます。E/flutter (18337): State が複数のAnimationController オブジェクトに使用されている場合、または State が他のオブジェクトに渡され、それらのオブジェクトがそれを合計で複数回使用する可能性がある場合、SingleTickerProviderStateMixin で混合する代わりに、通常の TickerProviderStateMixin を使用します。 。
これは、Flutter では、State オブジェクトが複数のAnimationController の TickerProvider として使用される場合、または他のオブジェクトに渡され、これらのオブジェクトがそれを合計で複数回使用する可能性がある場合、SingleTickerProviderStateMixin は使用できませんが、TickerProviderStateMixin を使用する必要があることを意味します。
SingleTickerProviderStateMixin は、単一のAnimationControllerを管理するためのTickerProviderオブジェクトを提供するミックスインクラスです。複数のAnimationControllerが同じSingleTickerProviderStateMixinを使用している場合、上記のエラーが発生します。
TickerProviderStateMixin は、複数のAnimationControllerで共有できるTickerProviderオブジェクトを提供するクラスです。したがって、複数のAnimationController間でTickerProviderを共有する必要がある場合は、StateクラスでSingleTickerProviderStateMixinの代わりにTickerProviderStateMixinを使用してください。
TickerProviderStateMixin を使用したサンプル コードを次に示します。
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> with TickerProviderStateMixin {
AnimationController _controller1;
AnimationController _controller2;
@override
void initState() {
super.initState();
_controller1 = AnimationController(vsync: this, duration: Duration(seconds: 1));
_controller2 = AnimationController(vsync: this, duration: Duration(seconds: 2));
}
@override
void dispose() {
_controller1.dispose();
_controller2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container();
}
}
复制代码
このサンプル コードでは、State クラスのミックスインとして TickerProviderStateMixin を使用します。これにより、_initState メソッドで 2 つのアニメーションコントローラー オブジェクトを作成し、TickerProvider をその State オブジェクトと共有できるようになります。State オブジェクトが破棄されると、2 つのAnimationController オブジェクトも破棄されます。
TickerProviderStateMixin に変更しました。OK、完璧に合格しました。問題が解決しました!