TabController构造函数中的`vsync`属性

Kam*_*icz 14 tabcontrol dart flutter

根据这个:示例代码

我创建了自己的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(),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在行:_tabController = new TabController(vsync: this, length: choices.length);我收到错误此消息:

错误:无法将参数类型"_MyAppState"分配给参数类型"TickerProvider".([swap] lib/main.dart中的argument_type_not_assignable:24)

我的代码出了什么问题?

Col*_*son 32

添加with TickerProviderStateMixin到您State的课程声明的末尾.


Har*_*mar 12

只需with TickerProviderStateMixin在 extends 状态类的末尾添加如下:

class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
//...
}
Run Code Online (Sandbox Code Playgroud)


小智 11

在类状态末尾添加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();
  }
}
Run Code Online (Sandbox Code Playgroud)


Jit*_*med 10

在 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,
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


Shu*_*oni 8

正如前面的回答,添加mixinTickerProviderStateMixin应该可以完成这项工作,或者SingleTickerProviderStateMixin如果您只需要Single,也可以使用Ticker

但是到底是TickerProviders什么呢?

vsync以一个TickerProvider参数作为参数,这就是我们使用的原因,SingleTickerProviderStateMixin并且正如其所描述的TickerProvider提供那样Ticker,它仅表示它向我们的应用程序告知了帧更新(或屏幕更新),以便我们AnimationController可以生成新值并可以重绘动画小部件。


jit*_*555 8

问题很笼统,所以需要更多描述

垂直同步用于

  • 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,
  );
Run Code Online (Sandbox Code Playgroud)

TabController内部用于AnimationController标签栏状态的渲染


小智 7

上面的答案是正确的,但您必须在类中声明一个选项卡并从 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();
  }
Run Code Online (Sandbox Code Playgroud)