如何检测 Flutter 中的 TabBar 变化?

Ash*_*tav 13 tabbar dart flutter

我需要在滑动时检测 TabBar 然后在控制台上打印一些东西,我该怎么做?这是我的代码。

bottomNavigationBar: new Material(
             color: Colors.blueAccent,
             child: new TabBar(
               onTap: (int index){ setState(() {
                 _onTap(index);
               });},

               indicatorColor: Colors.white,
               controller: controller,
               tabs: <Widget>[
                 new Tab(icon: new Icon(Icons.shopping_basket)),
                 new Tab(icon: new Icon(Icons.store)),
                 new Tab(icon: new Icon(Icons.local_offer)),
                 new Tab(icon: new Icon(Icons.assignment)),
                 new Tab(icon: new Icon(Icons.settings)),

               ],
             )
           ),
Run Code Online (Sandbox Code Playgroud)

non*_*hto 17

您需要向选项卡控制器添加一个侦听器 - 可能在initState.

controller.addListener((){
   print('my index is'+ controller.index.toString());
});
Run Code Online (Sandbox Code Playgroud)


liv*_*ove 9

这是一个完整的例子。使用 TabController 并使用 addListener 添加回调。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      home: MyTabbedPage(),
    );
  }
}

class MyTabbedPage extends StatefulWidget {
  const MyTabbedPage({Key key}) : super(key: key);
  @override
  _MyTabbedPageState createState() => _MyTabbedPageState();
}

class _MyTabbedPageState extends State<MyTabbedPage> with SingleTickerProviderStateMixin {
  var _context;

  final List<Tab> myTabs = <Tab>[
    Tab(text: 'LEFT'),
    Tab(text: 'RIGHT'),
  ];

  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(vsync: this, length: myTabs.length);

    _tabController.addListener(_handleTabSelection);
  }

  void _handleTabSelection() {
    if (_tabController.indexIsChanging) {
      switch (_tabController.index) {
        case 0:
          Scaffold.of(_context).showSnackBar(SnackBar(
            content: Text('Page 1 tapped.'),
            duration: Duration(milliseconds: 500),
          ));
          break;
        case 1:
          Scaffold.of(_context).showSnackBar(SnackBar(
            content: Text('Page 2 tapped.'),
            duration: Duration(milliseconds: 500),
          ));
          break;
      }
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        bottom: TabBar(
          controller: _tabController,
          tabs: myTabs,
        ),
      ),
      body: Builder(
        builder: (context) {
          _context = context;
          return TabBarView(
            controller: _tabController,
            children: 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)

  • 仅当我们点击选项卡栏项目时 ```indexIsChanging``` 才为 true,否则为 false(当滑动选项卡栏视图时) (8认同)
  • @VinothVino是的,但是 `if (!_tabController.indexIsChanging) print(_tabController.index);` 实际上每次切换选项卡时都会打印一次(通过点击 **AND** 来滑动)。这是因为通过点击切换选项卡时侦听器被调用两次 (2认同)

jit*_*555 8

滑动功能不是由onTap()函数提供的,因为它TabController被使用

class TabBarDemo extends StatefulWidget {
  @override
  _TabBarDemoState createState() => _TabBarDemoState();
}

class _TabBarDemoState extends State<TabBarDemo>
    with SingleTickerProviderStateMixin {
  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());
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          bottom: TabBar(
            onTap: (index) {
              // Should not used it as it only called when tab options are clicked,
              // not when user swapped
            },
            controller: _controller,
            tabs: list,
          ),
          title: Text('Tabs Demo'),
        ),
        body: TabBarView(
          controller: _controller,
          children: [
            Center(
                child: Text(
                  _selectedIndex.toString(),
                  style: TextStyle(fontSize: 40),
                )),
            Center(
                child: Text(
                  _selectedIndex.toString(),
                  style: TextStyle(fontSize: 40),
                )),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Github 仓库:

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

输出:

在此处输入图片说明

  • 工作得很好,但是 `addListener()` 在选项卡更改时被调用两次。有办法去掉吗? (4认同)