因为SingleTickerProviderStateMixin都是限制在State上使用的。这个可以看下源码:

而TabController实例化里面有个参数vsync 是需要在StatefulWidget的state上with SingleTickerProviderStateMixin才能获取符合vsync实例。因此提出两个问题:
一、请问下用了getx的话要怎么使用tabController之类的需要withSingleTickerProviderStateMixin的View呢?
答:如果不考虑tabView监听的话,可以用DefaultTabController。
二、假如我又需要自己控制TabController呢,DefaultTabController不能监听到tab的点击处理事件,咋办?
答:用getx的controller里添加GetSingleTickerProviderStateMixin
正好因为项目中遇到这个问题,网上搜了下,不少同学也遇到了。比如
小呆呆666的文章《Flutter GetX使用---简洁的魅力》有同学就提出此疑问,
另外我在stackoverflow上也看到老外也有位同学碰到这个问题,
其实处理方式也很简单,getx提供了GetSingleTickerProviderStateMixin去处理tabBarView的tab点击监听事件的。在自定义Controller的时候继承GetxController,同时with GetSingleTickerProviderStateMixin就能达到需求。例如:
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
-
- class MyTabController extends GetxController
- with GetSingleTickerProviderStateMixin {
- final List
myTabs = [ - Tab(text: '第一个tab'),
- Tab(text: '第二个tab'),
- ];
-
- TabController? tabController;
-
- @override
- void onInit() {
- super.onInit();
- tabController = TabController(vsync: this, length: myTabs.length);
- tabController?.addListener(() {
- ///避免addListener调用2次
- if (tabController?.index == tabController?.animation?.value) {
- print("点击了下标为${tabController?.index}的tab");
- }
- });
- }
-
- @override
- void onClose() {
- tabController?.dispose();
- super.onClose();
- }
- }
其实处理方法和在StatefulWidget里的state里一样,无非一个是在widget里,一个在Controller里。可以对比下:
class _MyHomePageState extends State with TickerProviderStateMixin{}
最后就是在widget,也就是view层调用就行了:
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_test_demo/MyTabController.dart';
- import 'package:get/get.dart';
-
- ///author:331209
- ///Time:2022/8/8
- ///description:
- class MyTabView extends StatelessWidget {
- MyTabController controller = Get.put(MyTabController());
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text("tabview"),
- bottom: TabBar(
- controller: controller.tabController,
- tabs: controller.myTabs,
- ),
- ),
- body: TabBarView(
- controller: controller.tabController,
- children: controller.myTabs.map((Tab tab) {
- final String label = tab.text!.toLowerCase();
- return Center(
- child: Text(
- ' $label ',
- style: const TextStyle(fontSize: 36),
- ),
- );
- }).toList(),
- ));
- }
- }
其实就是getx官网没给出具体的方案说明而已或者一般比较难找到此实现方案,导致很多同学想着在外层包层StatefulWidget来处理TabController,细思极恐,如果这样操作的话,就简单问题复杂化了。