venom202
venom202

Reputation: 341

Flutter tabcontroller index does not respond to changes in the tabbarview

Flutter tabcontroller detects the change in the tabbar but does not know the change in the tabbarview.

Listener causes the text of the floatingactionbutton to change, but there is no response when the tabbarview changes.

class TabPageState extends State<TabPage> with SingleTickerProviderStateMixin {

  TabController _controller;
  int _currentIndex = 0;

  @override
  void initState() {
    super.initState();
    _controller = TabController(vsync: this, length: 2);
    _controller.addListener(_handleTabSelection);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Tab'),
        bottom: TabBar(
          controller: _controller,
          tabs: <Widget>[
            Tab(icon: Icon(Icons.laptop_mac),),
            Tab(icon: Icon(Icons.desktop_mac),),
          ],
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: <Widget>[
          Center(child: Text('laptop'),),
          Center(child: Text('desctop'),),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){},
        child: Text('$_currentIndex'),
      ),
    );
  }

  _handleTabSelection() {
    if (_controller.indexIsChanging) {
      setState(() {
        _currentIndex = _controller.index;
      });
    }
  }
}

Upvotes: 33

Views: 51697

Answers (2)

Jitesh Mohite
Jitesh Mohite

Reputation: 34270

Doc Says:

indexIsChanging : True while we're animating from [previousIndex] to [index] as a
consequence of calling [animateTo]. This value is true during the [animateTo] animation that's triggered when /// the user taps a [TabBar] tab. It is false when [offset] is changing as a /// consequence of the user dragging (and "flinging") the [TabBarView].

  bool get indexIsChanging => _indexIsChangingCount != 0;
  int _indexIsChangingCount = 0;

Code:

  TabController _controller;
  int _selectedIndex = 0;

  List<Widget> list = [
    Tab(icon: Icon(Icons.card_travel)),
    Tab(icon: Icon(Icons.add_shopping_cart)),
  ];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    // Create TabController for getting the index of current tab
    _controller = TabController(length: list.length, vsync: this);

    _controller.addListener(() {
      setState(() {
        _selectedIndex = _controller.index;
      });
      print("Selected Index: " + _controller.index.toString());
    });
  }

Sample: https://github.com/jitsm555/Flutter-Problems/tree/master/tab_bar_tricks

Output:

enter image description here

Upvotes: 12

diegoveloper
diegoveloper

Reputation: 103551

just remove the condition :

  if (_controller.indexIsChanging) {

Because every time you start changing from previousIndex to the currentIndex, you rebuild the widget and your _controller.index is the same as your initial index.

This should work :

            _handleTabSelection() {
                  setState(() {
                    _currentIndex = _controller.index;
                  });
              }

Upvotes: 35

Related Questions