Dart 如何检测颤振中的TabBar变化?
我需要在我刷卡时检测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);
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;
}
}
}