PageView 内嵌套 TabBarView 的滑动冲突
要解决 PageView 内嵌套 TabBarView 的滑动冲突,并在 TabBarView 滑动到边界时将滑动事件提交给上一级的 PageView,可以使用 NotificationListener 和自定义的 TabBarView 来实现滑动事件的传递。以下是具体的实现方法:
import 'package:flutter/material.dart';
import '../../util/theme_util.dart';///主体框架---- 筛选工单状态
class WorkTabBarPage extends StatefulWidget {late PageController? _pageController;WorkTabBarPage(this._pageController, {Key? key,}) : super(key: key); _WorkTabBarState createState() => _WorkTabBarState();
}class _WorkTabBarState extends State<WorkTabBarPage>with SingleTickerProviderStateMixin {late TabController _tabController;int _currentIndex = 0;List<Map<String, dynamic>> _tabData = [{'title': '全部订单', 'count': 0},{'title': '待提交', 'count': 5},{'title': '已提交', 'count': 3},{'title': '待处理', 'count': 2},{'title': '已处理', 'count': 5},{'title': '已完成', 'count': 3},];void initState() {super.initState();_tabController = TabController(length: _tabData.length, vsync: this);_tabController.addListener(_handleTabSelection);}void _handleTabSelection() {if (_tabController.indexIsChanging) {setState(() {_currentIndex = _tabController.index;});}}void dispose() {_tabController.dispose();super.dispose();} Widget build(BuildContext context) {return Scaffold(backgroundColor: ThemeUtils.getBgProminent(context),appBar: AppBar(backgroundColor: ThemeUtils.getBgProminent(context),title: TabBar(isScrollable: true,// 设置标题栏可滚动indicator: UnderlineTabIndicator(borderSide: BorderSide(width: 2.0, color: ThemeUtils.getThemeColor(context)),// 设置选中下的横线颜色和宽度insets: EdgeInsets.symmetric(horizontal: 10.0),),dividerColor: Colors.transparent,indicatorSize: TabBarIndicatorSize.label,// 设置下划线的长度为标签的宽度labelColor: ThemeUtils.getThemeColor(context),// 设置选中标签的颜色unselectedLabelColor: ThemeUtils.getTextDeepColor(context),labelStyle: TextStyle(fontSize: 16.0, // 选中时的字体大小fontWeight: FontWeight.bold, // 选中时的字体加粗),unselectedLabelStyle: TextStyle(fontSize: 14.0, // 未选中时的字体大小fontWeight: FontWeight.normal, // 未选中时的字体加粗),controller: _tabController,tabAlignment: TabAlignment.start,tabs: _tabData.map((tab) {return Tab(child: Row(children: [Text(tab['title']),if (tab['count'] > 0)Container(padding: EdgeInsets.all(2),decoration: BoxDecoration(color: Colors.red,borderRadius: BorderRadius.circular(8),),constraints: BoxConstraints(minWidth: 14,minHeight: 14,),child: Text(tab['count'].toString(),style: TextStyle(color: Colors.white,fontSize: 10,),textAlign: TextAlign.center,),),],),);}).toList(),),),body: _buildCustomTabBarView(),);}Widget _buildCustomTabBarView() {return NotificationListener<ScrollNotification>(onNotification: (ScrollNotification notification) {if (notification is ScrollEndNotification) {// Check if the TabBarView has reached the beginning or endif (_tabController.index <= 0) {print('cexxxxx001 ${_tabController.index} extentBefore ${notification.metrics.extentBefore} extentAfter ${notification.metrics.extentAfter}');// Reached the beginning, pass the left swipe to the PageViewif (notification.metrics.extentBefore == 0) {widget. _pageController!.previousPage(duration: const Duration(milliseconds: 300),curve: Curves.ease,);print('cexxxxx001');}} else if (_tabController.index >= _tabData.length - 1) {print('cexxxxx002 ${_tabController.index} extentAfter ${notification.metrics.extentAfter} extentBefore ${notification.metrics.extentBefore}');// Reached the end, pass the right swipe to the PageViewif (notification.metrics.extentAfter == 0) {widget._pageController!.nextPage(duration: const Duration(milliseconds: 300),curve: Curves.ease,);print('cexxxxx002');}}}return false;},child: TabBarView(controller: _tabController,children: _tabData.map((tab) {return Container(child: Center(child: Text('这里是${tab['title']}页面内容'),),);}).toList(),),);}
}