Dart 如何检测颤振中的TabBar变化?

Dart 如何检测颤振中的TabBar变化?,dart,flutter,tabbar,Dart,Flutter,Tabbar,我需要在我刷卡时检测TabBar,然后在控制台上打印一些东西,我如何才能做到这一点?这是我的密码 bottomNavigationBar: new Material( color: Colors.blueAccent, child: new TabBar( onTap: (int index){ setState(() { _onTap(index);

我需要在我刷卡时检测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)),

               ],
             )
           ),
bottomNavigationBar:新材质(
颜色:Colors.blueAccent,
孩子:新的TabBar(
onTap:(int索引){setState(){
_onTap(索引);
});},
指示颜色:颜色。白色,
控制器:控制器,
选项卡:[
新建选项卡(图标:新建图标(图标.购物篮)),
新建选项卡(图标:新建图标(Icons.store)),
新建选项卡(图标:新建图标(图标.本地提供)),
新建选项卡(图标:新建图标(Icons.assignment)),
新建选项卡(图标:新建图标(图标.设置)),
],
)
),

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

controller.addListener((){
   print('my index is'+ controller.index.toString());
});

您可以通过添加以下内容禁用
TabBarView
上的滑动效果:

physics: NeverScrollableScrollPhysics(),
并声明一个
TabController
并将其分配给您的
TabBar
TabBarView

TabController _tabController;


我们可以使用
NotificationListener
Widget来监听选项卡滚动通知

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: NotificationListener(
          onNotification: (scrollNotification) {
            if (scrollNotification is ScrollUpdateNotification) {
              _onStartScroll(scrollNotification.metrics);
            }
          },
          child: _buildTabBarAndTabBarViews(),
    );
  }

  _onStartScroll(ScrollMetrics metrics) {
    print('hello world');
  }
}

这里有一个完整的例子。使用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(),
          );
        },
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“演示”,
主页:MyTabbedPage(),
);
}
}
类MyTabbedPage扩展StatefulWidget{
constmytabbedpage({Key}):super(Key:Key);
@凌驾
_MyTabbedPageState createState()=>\u MyTabbedPageState();
}
类_MyTabbedPageState使用SingleTickerProviderStateMixin扩展状态{
var_语境;
最终列表myTabs=[
选项卡(文本:“左”),
选项卡(文本:“右”),
];
TabController\u TabController;
@凌驾
void initState(){
super.initState();
_tabController=tabController(vsync:this,length:myTabs.length);
_tabController.addListener(_handleabselection);
}
void_handletabs选举(){
if(tab controller.indexIsChanging){
开关(选项卡控制器索引){
案例0:
Scaffold.of(_context).showSnackBar(SnackBar(
内容:文本(第1页),
持续时间:持续时间(毫秒:500),
));
打破
案例1:
Scaffold.of(_context).showSnackBar(SnackBar(
内容:文本(第2页),
持续时间:持续时间(毫秒:500),
));
打破
}
}
}
@凌驾
无效处置(){
_tabController.dispose();
super.dispose();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
底部:选项卡栏(
控制器:\ tab控制器,
标签:我的标签,
),
),
车身:建造商(
生成器:(上下文){
_上下文=上下文;
返回选项卡视图(
控制器:\ tab控制器,
子项:myTabs.map((选项卡){
最终字符串标签=tab.text.toLowerCase();
返回中心(
子:文本(
'这是$label选项卡',
样式:常量文本样式(字体大小:36),
),
);
}).toList(),
);
},
),
);
}
}

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),
                )),
          ],
        ),
      ),
    );
  }
}
类TabBarDemo扩展StatefulWidget{ @凌驾 _TabBarDemoState createState()=>TabBarDemoState(); } 类\u TabBarDemoState扩展状态 使用SingleTickerProviderStateMixin{ TabController\u控制器; int _selectedIndex=0; 列表=[ 选项卡(图标:图标(Icons.card_travel)), 选项卡(图标:图标(图标.添加购物车)), ]; @凌驾 void initState(){ //TODO:实现initState super.initState(); //创建TabController以获取当前选项卡的索引 _controller=TabController(长度:list.length,vsync:this); _controller.addListener(){ 设置状态(){ _selectedIndex=\u controller.index; }); 打印(“所选索引:”+_controller.Index.toString()); }); } @凌驾 小部件构建(构建上下文){ 返回材料PP( 家:脚手架( appBar:appBar( 底部:选项卡栏( onTap:(索引){ //不应使用它,因为它仅在单击选项卡选项时调用, //不是在用户交换时 }, 控制器:_控制器, 选项卡:列表, ), 标题:文本(“选项卡演示”), ), 正文:选项卡视图( 控制器:_控制器, 儿童:[ 居中( 子:文本( _已选择dex.toString(), 样式:TextStyle(字体大小:40), )), 居中( 子:文本( _已选择dex.toString(), 样式:TextStyle(字体大小:40), )), ], ), ), ); } }
Github:

输出:

扭曲底部导航栏中的选项卡。它将为您提供选项onTap(),您可以在其中检查将单击哪个选项卡

使用此代码,您还可以在点击Tab时重定向到特定页面

导入“包装:颤振/材料.省道”;
类BottomBarList扩展了StatefulWidget{
@凌驾
_BottomBarListState createState()=>\u BottomBarListState();
}
类_BottomBarListState扩展状态{
int bottomSelectedIndex=0;
int _selectedIndex=0;
列表_widgetOptions=[
AllMovieList(),
MovieDescription(),
];
@凌驾
小部件构建(BuildC)
import 'package:flutter/material.dart';
    
    
    class BottomBarList extends StatefulWidget {
      @override
      _BottomBarListState createState() => _BottomBarListState();
    }
    
    class _BottomBarListState extends State<BottomBarList> {
      int bottomSelectedIndex = 0;
      int _selectedIndex = 0;
    
    
      List<Widget> _widgetOptions = <Widget>[
        AllMovieList(),
        MovieDescription(),
    
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          //  appBar: AppBar(),
          bottomNavigationBar: bottomBar(),
          body:_widgetOptions.elementAt(_selectedIndex),
        );
      }
    
      bottomBar() {
        return BottomNavigationBar(
    
          type: BottomNavigationBarType.shifting,
          unselectedItemColor: Colors.grey,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.tv),
              title: Text('Home'),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.star),
              title: Text('Business'),
            ),
          ],
          currentIndex: _selectedIndex,
          selectedItemColor: Colors.black,
          backgroundColor: Colors.orange,
          onTap: _onItemTapped,
        );
      }
    
    
      void _onItemTapped(int index) {
        setState(() {
          _selectedIndex = index;
        });
      }
    }
import 'package:flutter/material.dart';

import '../widgets/basic_dialog.dart';
import 'sign_in_form.dart';
import 'sign_up_form.dart';

class LoginDialog extends StatefulWidget {
  @override
  _LoginDialogState createState() => _LoginDialogState();
}

class _LoginDialogState extends State<LoginDialog>
    with SingleTickerProviderStateMixin {
  int activeTab = 0;
  TabController controller;

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

  @override
  Widget build(BuildContext context) {
    return NotificationListener(
      onNotification: (ScrollNotification notification) {
        setState(() {
          if (notification.metrics.pixels <= 100) {
            controller.index = 0;
          } else {
            controller.index = 1;
          }
        });

        return true;
      },
      child: BasicDialog(
        child: Container(
          height: controller.index == 0
              ? MediaQuery.of(context).size.height / 2.7
              : MediaQuery.of(context).size.height / 1.8,
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              TabBar(
                controller: controller,
                tabs: <Widget>[
                  Padding(
                    padding: const EdgeInsets.all(5.0),
                    child: Text('Sign In'),
                  ),
                  Padding(
                    padding: const EdgeInsets.all(5.0),
                    child: Text('Sign up'),
                  ),
                ],
              ),
              Expanded(
                child: TabBarView(
                  controller: controller,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: SingleChildScrollView(
                        child: SignInForm(),
                      ),
                    ),

                    // If a container is not displayed during the tab switch to tab0, renderflex error is thrown because of the height change.
                    controller.index == 0
                        ? Container()
                        : Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: SingleChildScrollView(
                              child: SignUpForm(),
                            ),
                          ),
                  ],
                ),
              )
            ],
          ),
        ),
      ),
    );
  }
}
class HandlingTabChanges extends State<JsonTestDetailFrame> with SingleTickerProviderStateMixin {
  late final TabController _tabController;
  final int _tabLength = 2;

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: _tabLength,
      child: Scaffold(
        appBar: AppBar(
          title: Text("Some title"),
          bottom: TabBar(
            controller: _tabController,
            tabs: [
              Icon(Icons.settings),
              Icon(Icons.list_alt),
            ],
          ),
        ),
        body: NotificationListener(
          onNotification: (scrollNotification) {
            if (scrollNotification is ScrollEndNotification) _onTabChanged();
            return false;
          },
          child: TabBarView(
            controller: _tabController,
            children: [
              SomeWidget1(),
              SomeWidget2(),
            ],
          ),
        ),
      ),
    );
  }

  void _onTabChanged() {
    switch (_tabController.index) {
      case 0:
        // handle 0 position
        break;
      case 1:
        // handle 1 position
        break;
    }
  }
}