如何使用 Flutter GetX 构建 TabView

Pat*_*tas 6 tabview flutter flutter-layout flutter-get

我正在尝试使用 Flutter 和GetX构建一个用于状态管理的应用程序,在我的一个页面中,我需要在页面中间构建一个 TabView 小部件,我已经找到了很多解释如何构建 TabView 的内容小部件,如这篇文章这篇文章,但所有这些都扩展了一个带有SingleTickerProviderStateMixin状态控制器。

据我了解阅读文档,我不应该像那样使用 StatefulWidgets 和状态,但我无法弄清楚如何使用 GetX 架构来制定解决方案。

我已经在我的页面中尝试过:

class CourseDetailPage extends StatelessWidget {
  final TabController _tabController = Get.put(TabController(vsync: null, length: 2));
}
Run Code Online (Sandbox Code Playgroud)

class CourseDetailPage extends StatelessWidget {
  final TabController _tabController = TabController(vsync: null, length: 2);
}  
Run Code Online (Sandbox Code Playgroud)

但是 TabController 的 VSYNC 参数不能为空,我不知道我如何无法获得 TickerProvider 来填充它。

Bak*_*ker 16

以下是使用 GetX 控制器控制 TabView 的解决方案吗?

获取代码

SingleTickerProviderMixin 有一个 Get 版本,它实现了 TickerProvider 接口(使用 Flutter SDK 中的同一个 Ticker 类)。

它有一个好听的名字: SingleGetTickerProviderMixin

下面的示例基本上来自TabControllerFlutter 文档

从链接示例的 StatefulWidget 中,我将其内容转换为 GetxController ( MyTabController) 并添加了以下内容的混合SingleGetTickerProviderMixin

class MyTabController extends GetxController with SingleGetTickerProviderMixin {
  final List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  TabController controller;

  @override
  void onInit() {
    super.onInit();
    controller = TabController(vsync: this, length: myTabs.length);
  }

  @override
  void onClose() {
    controller.dispose();
    super.onClose();
  }
}
Run Code Online (Sandbox Code Playgroud)

MyTabController在无状态小部件中使用:

class MyTabbedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyTabController _tabx = Get.put(MyTabController());
    // ? init tab controller
    
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabx.controller,
          tabs: _tabx.myTabs,
        ),
      ),
      body: TabBarView(
        controller: _tabx.controller,
        children: _tabx.myTabs.map((Tab tab) {
          final String label = tab.text.toLowerCase();
          return Center(
            child: Text(
              'This is the $label tab',
              style: const TextStyle(fontSize: 36),
            ),
          );
        }).toList(),
      ),
    );
  }
}

Run Code Online (Sandbox Code Playgroud)

这是应用程序示例的其余部分,只需将其复制并粘贴到 Android Studio / VisualStudio Code 中即可运行:

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('GetX Tab Example'),
      ),
      body: Column(
        children: [
          Expanded(
            flex: 1,
            child: Container(
              alignment: Alignment.center,
              child: Text('Some random stuff'),
            ),
          ),
          Expanded(
            flex: 4,
            child: MyTabbedWidget(),
          )
        ],
      ),
    );
  }
}

class MyTabController extends GetxController with SingleGetTickerProviderMixin {
  final List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  TabController controller;

  @override
  void onInit() {
    super.onInit();
    controller = TabController(vsync: this, length: myTabs.length);
  }

  @override
  void onClose() {
    controller.dispose();
    super.onClose();
  }
}

class MyTabbedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyTabController _tabx = Get.put(MyTabController());
    // ? init tab controller
    
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabx.controller,
          tabs: _tabx.myTabs,
        ),
      ),
      body: TabBarView(
        controller: _tabx.controller,
        children: _tabx.myTabs.map((Tab tab) {
          final String label = tab.text.toLowerCase();
          return Center(
            child: Text(
              'This is the $label tab',
              style: const TextStyle(fontSize: 36),
            ),
          );
        }).toList(),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • “SingleGetTickerProviderMixin”和“GetSingleTickerProviderStateMixin”均已弃用,现在您可以使用它“SingleGetTickerProviderMixin”。 (2认同)