Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build a TabView using Flutter GetX

I'm trying to build a app using Flutter with GetX for State Management, and in one of my pages i need to build a TabView widget in the middle of the page, i already found a lot of stuff explaining how to build a TabView as widget, as this post and this article, but all of these extends a State controller with a SingleTickerProviderStateMixin.

As i understand reading the documentation, i'm not supposed to use StatefulWidgets and States like that, but i cant figure out how to elaborate a solution using the GetX architecture.

I already tried in my page things like:

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

and

class CourseDetailPage extends StatelessWidget {
  final TabController _tabController = TabController(vsync: null, length: 2);
}  

But the VSYNC argument for the TabController cannot be null, and i don't figure out how i cant obtain a TickerProvider to populate it.

like image 976
Patrick Freitas Avatar asked Sep 16 '20 16:09

Patrick Freitas


People also ask

Is GetX good for Flutter?

Obviously, both are used for state management. However, experienced Flutter devs do not recommend GetX. Do not use GetX.

How do I create a TabBar in Flutter?

You can create tabs using the TabBar widget. In this example, create a TabBar with three Tab widgets and place it within an AppBar . return MaterialApp( home: DefaultTabController( length: 3, child: Scaffold( appBar: AppBar( bottom: const TabBar( tabs: [ Tab(icon: Icon(Icons. directions_car)), Tab(icon: Icon(Icons.

What is Rx in GetX Flutter?

This stream is 'reactive', which means it can change value in reaction to events (like click of a button). These reactive streams are referred by 'Rx' in GetX. So, RxInt means a stream of variables of int datatype.


1 Answers

Would the following be a solution to using a GetX controller to control a TabView?

GetTicker

There's a Get version of SingleTickerProviderMixin which implements the TickerProvider interface (using the same Ticker class from Flutter SDK).

It has a catchy name: GetSingleTickerProviderStateMixin

(Updated 21-12-20: SingleGetTickerProviderMixin has been deprecated with latest GetX. Thanks to commenter pointing this out.)

The below example is basically from the Flutter docs for TabController.

From the linked example's StatefulWidget I transplanted its contents into a GetxController (MyTabController) and added mixin of SingleGetTickerProviderMixin:

class MyTabController extends GetxController with GetSingleTickerProviderStateMixin {
  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();
  }
}

To use MyTabController inside a Stateless widget:

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(),
      ),
    );
  }
}

Here's the rest of the app example to just copy & paste into Android Studio / VisualStudio Code to run:

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 GetSingleTickerProviderStateMixin {
  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(),
      ),
    );
  }
}
like image 111
Baker Avatar answered Oct 26 '22 14:10

Baker