使用Flutter自带的TabBar切换动画文字会有抖动问题,也可以修改源码,我觉得没必要。
我们可以不使用这两个参数,自己通过部件的刷新来实现切换文字变大的效果就可以解决抖动问题。
主要是利用了AnimatedDefaultTextStyle。
当然也可以直接改变字体大小fontSize,不使用动画。
demo:
class HomePage7 extends StatefulWidget {
@override
_HomePage7State createState() => _HomePage7State();
}
class _HomePage7State extends State<HomePage7> with TickerProviderStateMixin {
List<String>? _tabs;
TabController? _controller;
int _currentIndex = 0;
@override
void initState() {
super.initState();
_tabs = ['哈哈哈1', '哈哈哈2', '哈哈哈3', '哈哈哈4', '哈哈哈5', '哈哈哈6'];
_controller = TabController(length: _tabs!.length, vsync: this);
//⚠️替换动画后,此时滑动切换view上面tab不会联动,可以考虑用addListener替换onTap实现,也可以禁掉滑动切换
_controller.addListener(() {
if (_controller.index == _controller.animation?.value) {
setState(() {
_currentIndex = _controller.index;
});
}
});
}
///build
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Container(
height: 100,
color: Colors.blue,
),
SizedBox(
height: 60,
child: Expanded(
child: Theme(
data: ThemeData(
brightness: Brightness.light,
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: TabBar(
isScrollable: true,
labelPadding: const EdgeInsets.only(left: 8, right: 8),
indicator: const BoxDecoration(),
controller: _controller,
// 不使用自带改变效果
// labelColor: Colors.black,
// labelStyle: const TextStyle(fontSize: 25),
// unselectedLabelColor: Colors.black45,
// unselectedLabelStyle: const TextStyle(fontSize: 15),
// tabs: _tabs!.map((e) => Text(e)).toList(),
tabs: _tabs!.asMap().entries.map((e) {
return _animatedTab(e.key, e.value);
}).toList(),
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
),
),
),
),
Expanded(
child: TabBarView(
controller: _controller,
children: _tabs!.asMap().entries.map((e) {
return _content(e.key, e.value);
}).toList(),
),
),
],
),
);
}
Widget _animatedTab(int index, String text) {
TextStyle normalStyle = const TextStyle(
color: Colors.black45,
fontSize: 15,
);
TextStyle selectedStyle = const TextStyle(
color: Colors.black,
fontSize: 25,
);
return Tab(
child: AnimatedDefaultTextStyle(
style: _currentIndex == index ? selectedStyle : normalStyle,
duration: const Duration(milliseconds: 100),
child: Text(text),
),
);
}
Widget _content(int index, String text) {
return Container(
color: Colors.lightBlueAccent,
alignment: Alignment.center,
child: Text('$index-$text'),
);
}
}
网友评论