我创建了一个选项卡小部件,可以按一个选项卡并将其高亮显示并设置动画,但是在按下另一个选项卡后,“预览”选项卡应动画化回其预览状态。
使用打击代码在您的IDE上运行。
import 'package:flutter/material.dart';
class AnimatedTabsOne extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 300.0,
height: 60.0,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0, 3.5),
// spreadRadius: 0.0,
blurRadius: 4.0,
),
]),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
BuildTab(),
BuildTab(),
BuildTab(),
],
),
);
}
}
class BuildTab extends StatefulWidget {
@override
_BuildTabState createState() => _BuildTabState();
}
class _BuildTabState extends State<BuildTab>
with SingleTickerProviderStateMixin {
Animation<double> animation;
AnimationController controller;
bool isVisible = false;
bool setActiveBackgroundColor = false;
animateNow() {
controller =
AnimationController(duration: Duration(milliseconds: 200), vsync: this);
controller.forward();
animation = Tween<double>(begin: 50, end: 150).animate(controller)
..addListener(() => setState(() {
setActiveBackgroundColor = true;
isVisible = true;
}));
// ..addStatusListener((AnimationStatus status) {
// if (status == AnimationStatus.completed) {
// controller.reverse();
// setState(() {
// setActiveBackgroundColor = false;
// isVisible = false;
// });
// }
// });
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
print(
"setActiveBackgroundColor $setActiveBackgroundColor, isVisible: $isVisible");
return InkWell(
key: UniqueKey(),
onTap: () => animateNow(),
child: Container(
width: animation?.value ?? 50,
height: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: setActiveBackgroundColor == true ? Colors.blue : Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.home),
Flexible(
child: Visibility(visible: isVisible, child: Text("Home")),
)
],
),
),
);
}
}
我试图使用全局键,并以另一种方式调用回调函数,但是它没有完成任务。
答案 0 :(得分:1)
最好使用AnimatedContainer
。我简化了您的代码。解决方案有多种,一切都取决于您,但是如果您仅具有此功能,那么这是一种具有最少重建触发器的好模式:
class AnimatedTabsOne extends StatefulWidget {
@override
_AnimatedTabsOneState createState() => _AnimatedTabsOneState();
}
class _AnimatedTabsOneState extends State<AnimatedTabsOne> {
int index;
final myTabs = [BuildTab(), BuildTab(), BuildTab()];
@override
Widget build(BuildContext context) {
return Container(
width: 300.0,
height: 60.0,
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0, 3.5),
// spreadRadius: 0.0,
blurRadius: 4.0,
),
]),
child: Row(
children: List<Widget>.from(
myTabs.map((tab) {
final index = myTabs.indexOf(tab);
return GestureDetector(
child: BuildTab(isVisible: this.index == index),
onTap: () {
if (this.index != index) {
setState(() {
this.index = index;
});
}
},
);
}),
),
),
);
}
}
class BuildTab extends StatelessWidget {
final bool isVisible;
BuildTab({this.isVisible = false});
@override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 200),
width: isVisible ? 150 : 50,
height: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: isVisible ? Colors.blue : Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.home),
Flexible(
child: Visibility(visible: isVisible, child: Text("Home")),
)
],
),
);
}
}