小部件不会与其他小部件重叠
Widget won't overlap other widget
这是一个 TabBar,当索引被选中时它会动画化。有没有办法让正在动画的长文本 LOOOOT 不重叠 TabBar,或者只是在 TabBar 的布局后面动画?
TabTest
class TabTest extends StatefulWidget {
@override
_TabTestState createState() => _TabTestState();
}
class _TabTestState extends State<TabTest> with TickerProviderStateMixin {
late TabController _tabController;
late List<AnimationController> _animationControllers;
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this)
..addListener(_listener);
_animationControllers = List.generate(
4,
(i) => AnimationController(
vsync: this,
duration: Duration(milliseconds: 750),
reverseDuration: Duration(milliseconds: 350),
));
}
@override
Widget build(BuildContext context) {
Widget _tab(IconData iconData, String text) {
const _tabTextStyle = TextStyle(
fontWeight: FontWeight.w300, fontSize: 12, color: Colors.black);
return SizedBox(
height: 50,
child: Tab(
icon: Icon(iconData, color: Colors.black),
child: Text(text, style: _tabTextStyle),
),
);
}
List<Widget> _tabs = [
_tab(Icons.card_giftcard, 'LOOOOOOOTTTT'),
_tab(Icons.confirmation_num_outlined, 'Voucher'),
_tab(Icons.emoji_events_outlined, 'Testing'),
_tab(Icons.wine_bar_outlined, 'Testing'),
];
List<Widget> _animationGenerator() {
return List.generate(
_tabs.length,
(index) => AnimatedBuilder(
animation: _animationControllers[index],
builder: (ctx, child) {
final child = _tabs[index];
final value = _animationControllers[index].value;
final angle = math.sin(value * math.pi * 2) * math.pi * 0.08;
print(angle);
return Transform.rotate(angle: angle, child: child);
}),
);
}
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100),
child: AppBar(
iconTheme: Theme.of(context).iconTheme,
title: Text(
'Tab Bar',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(20),
child: Container(
child: TabBar(
controller: _tabController,
labelPadding: EdgeInsets.only(top: 5.0, bottom: 2.0),
indicatorColor: Colors.black,
tabs: _animationGenerator(),
),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.white,
spreadRadius: 5.0,
offset: Offset(0, 3))
],
),
),
),
),
),
body: TabBarView(
controller: _tabController,
children: List.generate(
4,
(index) => FittedBox(
child: Text('Tab $index'),
)),
),
);
}
void _listener() {
if (_tabController.indexIsChanging) {
_animationControllers[_tabController.previousIndex].reverse();
} else {
_animationControllers[_tabController.index].forward();
}
}
@override
void dispose() {
super.dispose();
_tabController.removeListener(_listener);
}
}
这就是我的。没有使用包。计划使用所选 Tab
的底部边框对 Container
进行动画处理。 (目前使用 SizedBox
包裹 Tab
)并在 TabBar
后面设置动画而不是重叠 TabBar
.
编辑:包括代码
用 clipRect 包装选项卡小部件。
这是一个 TabBar,当索引被选中时它会动画化。有没有办法让正在动画的长文本 LOOOOT 不重叠 TabBar,或者只是在 TabBar 的布局后面动画?
TabTest
class TabTest extends StatefulWidget {
@override
_TabTestState createState() => _TabTestState();
}
class _TabTestState extends State<TabTest> with TickerProviderStateMixin {
late TabController _tabController;
late List<AnimationController> _animationControllers;
@override
void initState() {
super.initState();
_tabController = TabController(length: 4, vsync: this)
..addListener(_listener);
_animationControllers = List.generate(
4,
(i) => AnimationController(
vsync: this,
duration: Duration(milliseconds: 750),
reverseDuration: Duration(milliseconds: 350),
));
}
@override
Widget build(BuildContext context) {
Widget _tab(IconData iconData, String text) {
const _tabTextStyle = TextStyle(
fontWeight: FontWeight.w300, fontSize: 12, color: Colors.black);
return SizedBox(
height: 50,
child: Tab(
icon: Icon(iconData, color: Colors.black),
child: Text(text, style: _tabTextStyle),
),
);
}
List<Widget> _tabs = [
_tab(Icons.card_giftcard, 'LOOOOOOOTTTT'),
_tab(Icons.confirmation_num_outlined, 'Voucher'),
_tab(Icons.emoji_events_outlined, 'Testing'),
_tab(Icons.wine_bar_outlined, 'Testing'),
];
List<Widget> _animationGenerator() {
return List.generate(
_tabs.length,
(index) => AnimatedBuilder(
animation: _animationControllers[index],
builder: (ctx, child) {
final child = _tabs[index];
final value = _animationControllers[index].value;
final angle = math.sin(value * math.pi * 2) * math.pi * 0.08;
print(angle);
return Transform.rotate(angle: angle, child: child);
}),
);
}
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100),
child: AppBar(
iconTheme: Theme.of(context).iconTheme,
title: Text(
'Tab Bar',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
),
),
centerTitle: true,
bottom: PreferredSize(
preferredSize: Size.fromHeight(20),
child: Container(
child: TabBar(
controller: _tabController,
labelPadding: EdgeInsets.only(top: 5.0, bottom: 2.0),
indicatorColor: Colors.black,
tabs: _animationGenerator(),
),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.white,
spreadRadius: 5.0,
offset: Offset(0, 3))
],
),
),
),
),
),
body: TabBarView(
controller: _tabController,
children: List.generate(
4,
(index) => FittedBox(
child: Text('Tab $index'),
)),
),
);
}
void _listener() {
if (_tabController.indexIsChanging) {
_animationControllers[_tabController.previousIndex].reverse();
} else {
_animationControllers[_tabController.index].forward();
}
}
@override
void dispose() {
super.dispose();
_tabController.removeListener(_listener);
}
}
这就是我的。没有使用包。计划使用所选 Tab
的底部边框对 Container
进行动画处理。 (目前使用 SizedBox
包裹 Tab
)并在 TabBar
后面设置动画而不是重叠 TabBar
.
编辑:包括代码
用 clipRect 包装选项卡小部件。