根据此:示例代码
我创建了自己的 TabController 实现:
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
TabController _tabController;
@override
void initState() {
super.initState();
_tabController = new TabController(vsync: this, length: choices.length);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
bottomNavigationBar: new Material(
color: Colors.blue,
child: new TabBar(
controller: _tabController,
isScrollable: false,
tabs: choices.map((Choice choice) {
return new Tab(
text: null,
icon: new Icon(choice.icon),
);
}).toList(),
),
),
appBar: new AppBar(
title: const Text('Swap'),
),
body: new TabBarView(
controller: _tabController,
children: choices.map((Choice choice) {
return new Padding(
padding: const EdgeInsets.all(16.0),
child: new ChoiceCard(choice: choice),
);
}).toList(),
),
),
);
}
}
在线:
_tabController = new TabController(vsync: this, length: choices.length);
我收到错误消息:
错误:参数类型“_MyAppState”无法分配给参数类型“TickerProvider”。 (argument_type_not_assignable 位于 [swap] lib/main.dart:24)
我的代码有什么问题?
将
with TickerProviderStateMixin
添加到 State
类声明的末尾。
只需在扩展状态类末尾添加
with TickerProviderStateMixin
,如下所示:
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
//...
}
如之前回答的,添加
mixin
,TickerProviderStateMixin
应该可以完成这项工作,或者如果您只需要一个 SingleTickerProviderStateMixin
,您也可以使用 Ticker
。
但是
真的有什么作用吗?TickerProviders
vsync
采用 TickerProvider
作为参数,这就是我们使用 SingleTickerProviderStateMixin
的原因,正如名称所描述的那样,TickerProvider
提供了 Ticker
,这意味着它告诉我们的应用程序有关框架更新(或屏幕更新)的信息,所以我们的 AnimationController
可以生成一个新值,并且我们可以重绘动画小部件。
在类状态末尾添加TickerProviderStateMixin
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with TickerProviderStateMixin {
MotionTabController? _tabController;
@override
void initState() {
super.initState();
_tabController = new MotionTabController(initialIndex: 1, vsync: this);
}
@override
void dispose() {
super.dispose();
_tabController!.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
}
问题很笼统,所以需要描述更多
垂直同步用于
vsync 是代表 TickerProvider 的属性(即 Tick 类似于时钟的滴答声,这意味着在每个特定的持续时间内 TickerProvider 将渲染类状态并重绘对象。)
仅在构造函数上需要 vsync 属性,当我们需要渲染组件或小部件以重绘和反映 UI 时,该构造函数需要在每个特定的偏移时间渲染其类状态。
vsync 可以与需要某些过渡或动画来重新渲染以绘制不同对象的类一起使用。
内部实施
TabController({ int initialIndex = 0, @required this.length, @required TickerProvider vsync })
: assert(length != null && length >= 0),
assert(initialIndex != null && initialIndex >= 0 && (length == 0 || initialIndex < length)),
_index = initialIndex,
_previousIndex = initialIndex,
_animationController = AnimationController.unbounded(
value: initialIndex.toDouble(),
vsync: vsync,
);
TabController
内部使用AnimationController
来渲染标签栏状态
在 GetX 中
我找到了一个解决方案,只需添加 SingleGetTickerProviderMixin 即可成为完整代码,如下所示:
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class ControllerViewModel extends GetxController with GetSingleTickerProviderStateMixin {
AnimationController _controller;
@override
void onInit() {
// TODO: implement onInit
super.onInit();
_controller = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 2500,
),
);
}
}
上面的答案是正确的,但你必须在类中声明一个标签栏并从 iniState 初始化标签栏,否则 vsync 变量不接受 'this' 以下代码可能对您有帮助。
class _MatchesState extends State<Matches> with SingleTickerProviderStateMixin {
TabController? tabController;
@override
void initState() {
tabController = TabController(
length: 2,
vsync: this,
initialIndex: 0,
);
super.initState();
}
在语句末尾添加任何 SingleTickerProviderStateMixin/ TickerProviderStateMixin mixins,如下所示:
例如:
class _ListingViewState 使用 SingleTickerProviderStateMixin { }
扩展 State
//I had the same problem, to solve it I just added
with SingleTickerProviderStateMixin{
//and finally add the following
TabController? _tabController;
@override
void initState() {
// TODO: implement initState
_tabController = TabController(initialIndex: 0, length: 3, vsync: this);
super.initState();
}