TabController 构造函数中的 `vsync` 属性
`vsync` property in TabController constructor
据此: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);
我收到错误消息:
error: The argument type '_MyAppState' can't be assigned to the parameter type 'TickerProvider'. (argument_type_not_assignable at [swap] lib/main.dart:24)
我的代码有什么问题?
将 with TickerProviderStateMixin
添加到 State
的 class 声明的末尾。
如前所述,添加 mixin
,TickerProviderStateMixin
应该可以完成工作,或者如果您只需要一个 Ticker
,也可以使用 SingleTickerProviderStateMixin
].
But what is Does TickerProviders
really do?
vsync
将 TickerProvider
作为参数,这就是我们使用 SingleTickerProviderStateMixin
的原因,正如名称描述的那样,TickerProvider
提供了 Ticker
,这就是它的意思告诉我们的应用程序有关帧更新(或屏幕更新)的信息,以便我们的 AnimationController
可以生成新值并且我们可以重绘动画小部件。
只需在extends状态class末尾添加with TickerProviderStateMixin
如下:
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
//...
}
在语句末尾添加任何这些 SingleTickerProviderStateMixin/ TickerProviderStateMixin mixins,如下所示:
例如:
class _ListingViewState extends State with SingleTickerProviderStateMixin { }
你所要做的就是添加到这个 - 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();
}
}
问题很笼统,需要详细描述
垂直同步用于
vsync 是代表 TickerProvider 的 属性(即 Tick
类似于时钟的滴答声,这意味着在每个特定的持续时间
TickerProvider 将呈现 class 状态并重绘对象。)
vsync 属性 仅在需要渲染其 class 状态的构造函数上才需要重绘并反映 UI.
vsync 可以与 classes 一起使用,需要特定的过渡或动画来重新渲染以绘制不同的对象。
内部实现
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
来呈现标签栏状态
在class状态
末尾添加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();
}
}
在 GetX 中
我找到了一个解决方案,只需添加 SingleGetTickerProviderMixin 即可成为完整代码,如下所示:
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class ControllerViewModel extends GetxController with SingleGetTickerProviderMixin {
AnimationController _controller;
@override
void onInit() {
// TODO: implement onInit
super.onInit();
_controller = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 2500,
),
);
}
}
上面的答案是正确的,但你必须在 class 中声明一个标签栏并从 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();
}
据此: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);
我收到错误消息:
error: The argument type '_MyAppState' can't be assigned to the parameter type 'TickerProvider'. (argument_type_not_assignable at [swap] lib/main.dart:24)
我的代码有什么问题?
将 with TickerProviderStateMixin
添加到 State
的 class 声明的末尾。
如前所述,添加 mixin
,TickerProviderStateMixin
应该可以完成工作,或者如果您只需要一个 Ticker
,也可以使用 SingleTickerProviderStateMixin
].
But what is Does
TickerProviders
really do?
vsync
将 TickerProvider
作为参数,这就是我们使用 SingleTickerProviderStateMixin
的原因,正如名称描述的那样,TickerProvider
提供了 Ticker
,这就是它的意思告诉我们的应用程序有关帧更新(或屏幕更新)的信息,以便我们的 AnimationController
可以生成新值并且我们可以重绘动画小部件。
只需在extends状态class末尾添加with TickerProviderStateMixin
如下:
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
//...
}
在语句末尾添加任何这些 SingleTickerProviderStateMixin/ TickerProviderStateMixin mixins,如下所示:
例如:
class _ListingViewState extends State with SingleTickerProviderStateMixin { }
你所要做的就是添加到这个 - 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();
}
}
问题很笼统,需要详细描述
垂直同步用于
vsync 是代表 TickerProvider 的 属性(即 Tick 类似于时钟的滴答声,这意味着在每个特定的持续时间 TickerProvider 将呈现 class 状态并重绘对象。)
vsync 属性 仅在需要渲染其 class 状态的构造函数上才需要重绘并反映 UI.
vsync 可以与 classes 一起使用,需要特定的过渡或动画来重新渲染以绘制不同的对象。
内部实现
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
来呈现标签栏状态
在class状态
末尾添加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();
}
}
在 GetX 中
我找到了一个解决方案,只需添加 SingleGetTickerProviderMixin 即可成为完整代码,如下所示:
import 'package:get/get.dart';
import 'package:flutter/material.dart';
class ControllerViewModel extends GetxController with SingleGetTickerProviderMixin {
AnimationController _controller;
@override
void onInit() {
// TODO: implement onInit
super.onInit();
_controller = AnimationController(
vsync: this,
duration: const Duration(
milliseconds: 2500,
),
);
}
}
上面的答案是正确的,但你必须在 class 中声明一个标签栏并从 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();
}