Flutter 组件:列表复用,支持 TabBar 不可点击状态
Posted 一叶飘舟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 组件:列表复用,支持 TabBar 不可点击状态相关的知识,希望对你有一定的参考价值。
一、需求
工作中常遇到列表界面复用,每次敲重复代码有点繁琐,随顺手封装,方便复用;
值得注意的是flutter 中不可点击状态不是通过属性设置的,而是通过 IgnorePointer 组件实现的;
///TabBar+TabBarView
class TabBarTabBarView extends StatefulWidget
和
/// TabBar + PageViewW
class TabBarPageView extends StatefulWidget
二、screenshots
三、源码
TabBarTabBarView
//
// TabBarPageView.dart
// fluttertemplet
//
// Created by shang on 10/22/21 5:03 PM.
// Copyright © 10/22/21 shang. All rights reserved.
//
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertemplet/dartExpand/ddlog.dart';
import 'package:tuple/tuple.dart';
import 'package:flutter/material.dart';
///TabBar+TabBarView
class TabBarTabBarView extends StatefulWidget
final List<Tuple2<String, Widget>> items;
final Color? indicatorColor;
final Color? labelColor;
final PageController? pageController;
final TabController? tabController;
final ValueChanged<int> onPageChanged;
final bool Function(int)? canPageChanged;
final bool isTabBarTop;
TabBarTabBarView(
Key? key,
this.isTabBarTop = true,
required this.items,
this.indicatorColor,
this.labelColor,
this.pageController,
this.tabController,
required this.onPageChanged,
this.canPageChanged,
) : super(key: key);
@override
_TabBarTabBarViewState createState() => _TabBarTabBarViewState();
class _TabBarTabBarViewState extends State<TabBarTabBarView> with TickerProviderStateMixin
late TabController _tabController;
late TabController _tabController1 = TabController(length: widget.items.length, vsync: this);
///是否允许滚动
bool get canScrollable
if (widget.canPageChanged != null && widget.canPageChanged!(_tabController.index) == false)
return false;
return true;
@override
void initState()
_tabController = widget.tabController ?? TabController(length: widget.items.length, vsync: this)
..addListener(()
// ddlog(_tabController.index);
setState(()
_tabController1.animateTo( _tabController.index);
);
widget.onPageChanged(_tabController.index);
);
super.initState();
@override
void dispose()
_tabController.dispose();
super.dispose();
@override
Widget build(BuildContext context)
final list = [
_buildTabBar(),
_buildTabBarView(),
];
return Column(
mainAxisSize: MainAxisSize.min,
children: widget.isTabBarTop ? list : list.reversed.toList(),
);
Widget _buildTabBar()
final textColor = widget.labelColor ?? Theme
.of(context)
.colorScheme
.secondary;
final bgColor = widget.indicatorColor ?? Colors.white;
// final bgColor = Theme.of(context).colorScheme.secondary;
// final textColor = Colors.white;
BoxDecoration indicatorTop = BoxDecoration(
border: Border(
top: BorderSide(
// color: textColor ,
color: textColor,
width: 3.0
),
),
);
BoxDecoration indicatorBom = BoxDecoration(
border: Border(
bottom: BorderSide(
// color: textColor ,
color: textColor,
width: 3.0
),
),
);
final tabBar = TabBar(
controller: _tabController1,
tabs: widget.items.map((e) => Tab(text: e.item1)).toList(),
labelColor: textColor,
indicator: widget.isTabBarTop ? indicatorBom : indicatorTop,
onTap: (index)
// ddlog([index, _tabController.index]);
setState(()
_tabController.animateTo( _tabController1.index);
);
// widget.onPageChanged(_tabController.index);
,
);
if (!canScrollable)
return IgnorePointer(
child: tabBar,
);
if (widget.isTabBarTop)
return tabBar;
return Material(
color: bgColor,
child: SafeArea(
child: tabBar,
)
);
Widget _buildTabBarView()
return Expanded(
child: TabBarView(
controller: _tabController,
physics: canScrollable ? BouncingScrollPhysics() : NeverScrollableScrollPhysics(),
children: widget.items.map((e) => e.item2).toList(),
),);
TabBarPageView
//
// TabBarPageView.dart
// fluttertemplet
//
// Created by shang on 10/22/21 5:03 PM.
// Copyright © 10/22/21 shang. All rights reserved.
//
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertemplet/dartExpand/ddlog.dart';
import 'package:tuple/tuple.dart';
/// TabBar + PageViewW
class TabBarPageView extends StatefulWidget
final List<Tuple2<String, Widget>> items;
final Color? indicatorColor;
final Color? labelColor;
final PageController? pageController;
final TabController? tabController;
final ValueChanged<int> onPageChanged;
final bool Function(int)? canPageChanged;
final bool isTabBarTop;
TabBarPageView(
Key? key,
this.isTabBarTop = true,
required this.items,
this.indicatorColor,
this.labelColor,
this.pageController,
this.tabController,
required this.onPageChanged,
this.canPageChanged,
) : super(key: key);
@override
_TabBarPageViewState createState() => _TabBarPageViewState();
class _TabBarPageViewState extends State<TabBarPageView> with SingleTickerProviderStateMixin
late TabController _tabController;
late PageController _pageController;
///是否允许滚动
bool get canScrollable
if (widget.canPageChanged != null && widget.canPageChanged!(_tabController.index) == false)
return false;
return true;
@override
void initState()
_tabController = widget.tabController ?? TabController(length: widget.items.length, vsync: this);
_pageController = widget.pageController ?? PageController(initialPage: 0, keepPage: true);
// ..addListener(()
// ddlog(_pageController.page);
//
// );
super.initState();
@override
void dispose()
_tabController.dispose();
_pageController.dispose();
super.dispose();
@override
Widget build(BuildContext context)
final list = [
_buildTabBar(),
_buildPageView(),
];
return Column(
mainAxisSize: MainAxisSize.min,
children: widget.isTabBarTop ? list : list.reversed.toList(),
);
Widget _buildTabBar()
final textColor = widget.labelColor ?? Theme
.of(context)
.colorScheme
.secondary;
final bgColor = widget.indicatorColor ?? Colors.white;
// final bgColor = Theme.of(context).colorScheme.secondary;
// final textColor = Colors.white;
BoxDecoration indicatorTop = BoxDecoration(
border: Border(
top: BorderSide(
// color: textColor ,
color: textColor,
width: 3.0
),
),
);
BoxDecoration indicatorBom = BoxDecoration(
border: Border(
bottom: BorderSide(
// color: textColor ,
color: textColor,
width: 3.0
),
),
);
final tabBar = TabBar(
controller: _tabController,
tabs: widget.items.map((e) => Tab(text: e.item1)).toList(),
labelColor: textColor,
indicator: widget.isTabBarTop ? indicatorBom : indicatorTop,
onTap: (index)
// ddlog(index);
setState(()
_pageController.jumpToPage(index);
);
,
);
if (!canScrollable)
return IgnorePointer(
child: tabBar,
);
if (widget.isTabBarTop)
return tabBar;
return Material(
color: bgColor,
child: SafeArea(
child: tabBar,
)
);
Widget _buildPageView()
return Expanded(
child: PageView(
controller: _pageController,
physics: canScrollable ? BouncingScrollPhysics() : NeverScrollableScrollPhysics(),
children: widget.items.map((e) => e.item2).toList(),
onPageChanged: (index)
widget.onPageChanged(index);
setState(()
_tabController.animateTo(index);
);
,
));
以上是关于Flutter 组件:列表复用,支持 TabBar 不可点击状态的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 专题75 图解基本 TabBar 标签导航栏 #yyds干货盘点#