TabController 构造函数中的 `vsync` 属性
Posted
技术标签:
【中文标题】TabController 构造函数中的 `vsync` 属性【英文标题】:`vsync` property in TabController constructor 【发布时间】:2018-04-01 18:02:37 【问题描述】:据此:sample code
我创建了自己的 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)
我的代码有什么问题?
【问题讨论】:
【参考方案1】:在类状态末尾添加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();
【讨论】:
【参考方案2】:问题很笼统,需要多描述一下
垂直同步用于
vsync 是表示 TickerProvider 的属性(即 Tick 类似于时钟的滴答声,这意味着在每个特定的持续时间 TickerProvider 将呈现类状态并重绘对象。)
只有当我们需要渲染我们的组件或小部件以重绘和反映 UI 时,需要在每个特定偏移时间渲染其类状态的构造函数才需要 vsync 属性。
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
来呈现标签栏状态
【讨论】:
它看起来真的可能是一个可选参数。【参考方案3】:你所要做的就是添加到这个 - SingleTickerProviderStateMixin
旁边 State<MyApp>
正如@Shubham-Soni 上面所说的
只需更改这一行:
_MyAppState extends State<MyApp>
到这里:
_MyAppState extends State<MyApp>
with SingleTickerProviderStateMixin
这里是如何做到这一点的完整示例
class MyApp extends StatefulWidget
const MyApp(Key key) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
class _MyAppState extends State<MyApp>
with SingleTickerProviderStateMixin
TabController tabController;
void initState()
tabController =
TabController(length: tabsList.length, vsync: this, initialIndex: 0);
super.initState();
@override
Widget build(BuildContext context)
// TODO: implement build
throw UnimplementedError();
【讨论】:
【参考方案4】:在语句末尾添加任何这些 SingleTickerProviderStateMixin/ TickerProviderStateMixin 混合,如下所示:
例如:
class _ListingViewState 使用 SingleTickerProviderStateMixin
扩展 State
【讨论】:
【参考方案5】:只需在extends状态类的末尾添加with TickerProviderStateMixin
,如下:
class _MyAppState extends State<MyApp> with TickerProviderStateMixin
//...
【讨论】:
【参考方案6】:正如前面回答的那样,添加 mixin
,TickerProviderStateMixin
应该可以完成这项工作,或者如果您只需要单个 Ticker
,您也可以使用 SingleTickerProviderStateMixin
。
但是
TickerProviders
真的是做什么的呢?
vsync
将TickerProvider
作为参数,这就是我们使用SingleTickerProviderStateMixin
的原因,正如名称所描述的,TickerProvider
提供Ticker
,这仅仅意味着它告诉我们的应用程序有关框架更新(或屏幕更新) , 这样我们的AnimationController
就可以生成一个新的值,我们可以重新绘制动画小部件。
【讨论】:
【参考方案7】:将with TickerProviderStateMixin
添加到State
的类声明的末尾。
【讨论】:
就是这样。现在我在更改选项卡期间登录控制台很奇怪:Another exception was thrown: 'package:flutter/src/rendering/object.dart': Failed assertion: line 2257 pos 12: 'fragment is _InterestingSemanticsFragment': is not true.
听起来不相关,也许重启应用/升级你的 Flutter?
使用 StateMixin 可能会遇到热重载问题,如果这样做,请尝试使用 TickerProviderStateMixin 而不是 SingleTickerProviderStateMixin以上是关于TabController 构造函数中的 `vsync` 属性的主要内容,如果未能解决你的问题,请参考以下文章