Getx在Controller里添加TabController的处理

因为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上也看到老外也有位同学碰到这个问题,

How to build a TabView using Flutter GetX

   其实处理方式也很简单,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<Tab> myTabs = <Tab>[
    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<MyHomePage> 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,细思极恐,如果这样操作的话,就简单问题复杂化了。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chen_ShengJie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值