Jih*_*aji 4 dart flutter flutter-layout flutter-widget
如何自定义Flutter TabBar中的Tab指示器以达到下面的目标结果?
我该如何执行以下操作:
这是我的代码
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
var categoryTabs = <Tab>[...];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: categoryTabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('My App'),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size(100, 70),
child: Column(
children: [
TabBar(
indicatorSize: TabBarIndicatorSize.tab,
indicatorColor: Colors.transparent,
labelColor: colorPrimaryDark,
isScrollable: true,
unselectedLabelColor: Colors.white,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.white,
),
tabs: categoryTabs,
),
SizedBox(height: 10)
],
),
),
),
body: SafeArea(...),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
hie*_*trq 10
当选项卡控制器从一个索引动画到另一个索引时,您需要用于AnimatedBuilder监听选项卡控制器动画。使用这种方法,您可以自定义项目的过渡动画TabBar。例如:将您的TabBar实现更改为以下内容
TabBar(
tabs: tabs
.asMap().entries
.map((entry) => AnimatedBuilder(
animation: _tabController.animation,
builder: (ctx, snapshot) {
final forward = _tabController.offset > 0;
final backward = _tabController.offset < 0;
int _fromIndex;
int _toIndex;
double progress;
// This value is true during the [animateTo] animation that's triggered when the user taps a [TabBar] tab.
// It is false when [offset] is changing as a consequence of the user dragging the [TabBarView].
if (_tabController.indexIsChanging) {
_fromIndex = _tabController.previousIndex;
_toIndex = _tabController.index;
_cachedFromIdx = _tabController.previousIndex;
_cachedToIdx = _tabController.index;
progress = (_tabController.animation.value - _fromIndex).abs() / (_toIndex - _fromIndex).abs();
} else {
if (_cachedFromIdx == _tabController.previousIndex && _cachedToIdx == _tabController.index) {
// When user tap on a tab bar and the animation is completed, it will execute this block
// This block will not be called when user draging the TabBarView
_fromIndex = _cachedFromIdx;
_toIndex = _cachedToIdx;
progress = 1;
_cachedToIdx = null;
_cachedFromIdx = null;
} else {
_cachedToIdx = null;
_cachedFromIdx = null;
_fromIndex = _tabController.index;
_toIndex = forward
? _fromIndex + 1
: backward
? _fromIndex - 1
: _fromIndex;
progress = (_tabController.animation.value - _fromIndex).abs();
}
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: entry.key == _fromIndex
? Color.lerp(Colors.white, Colors.red.shade900, progress)
: entry.key == _toIndex
? Color.lerp(Colors.red.shade900, Colors.white, progress)
: Color.lerp(Colors.red.shade900, Colors.red.shade900, progress),
borderRadius: BorderRadius.circular(200),
),
child: Text(
entry.value.toUpperCase(),
style: TextStyle(
fontSize: 10,
letterSpacing: 0.4,
fontWeight: FontWeight.w700,
),
),
);
},
))
.toList(),
controller: _tabController,
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
indicatorWeight: 0,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(100),
),
physics: const ClampingScrollPhysics(),
unselectedLabelColor: Colors.white,
labelColor: Colors.red,
labelPadding: EdgeInsets.only(left: 12),
),
Run Code Online (Sandbox Code Playgroud)
请注意,在上面的示例中,我使用 2 个局部变量来跟踪当前和先前的索引。这专门用于处理用户在TabBar选项卡上单击以在一个索引到另一个索引之间设置动画的情况。将 log 命令放入AnimatedBuilder的构建器方法中以更好地理解它是如何工作的。
int _cachedFromIdx;
int _cachedToIdx;
Run Code Online (Sandbox Code Playgroud)
这是结果
检查这个代码
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
bottom: PreferredSize(
preferredSize: Size(100,20),
child: Column(
children: [
TabBar(
// indicatorSize: TabBarIndicatorSize.tab,
indicatorColor: Colors.transparent,
labelColor: Colors.white,
unselectedLabelColor: Colors.black,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.redAccent),
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.report_problem)),
Tab(icon: Icon(Icons.report_problem)),
],
),
SizedBox(height: 10,)
],
),
),
),
body: TabBarView(
children: [
Icon(Icons.directions_car),
Icon(Icons.directions_transit),
Icon(Icons.directions_bike),
],
)
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11485 次 |
| 最近记录: |