我有两个类:SideNavBar和ContentPage。 SideNavBar包含一个功能,当按下菜单上的某个项目时,该功能可为对象设置动画。 ContentPage包含一个PageView,当它更改时,我想在SideNavBar中使用参数执行该功能。
不包含该功能的ContentPage:
class ContentPage extends StatefulWidget {
@override
_ContentPageState createState() => _ContentPageState();
}
class _ContentPageState extends State<ContentPage> {
PageController controller;
@override
void initState() {
controller = PageController(
initialPage: 6
);
super.initState();
}
@override
Widget build(BuildContext context) {
return Material(
child: PageView(
controller: controller,
scrollDirection: Axis.vertical,
children: <Widget>[
menuSlides(),
menuSlides(),
menuSlides(),
menuSlides(),
menuSlides(),
menuSlides(),
],
onPageChanged: (int idx) {
print('animate function from SideNavBar');
},
)
);
}
}
包含以下功能的SideNavBar:
class SideNavBar extends StatefulWidget {
@override
_SideNavBarState createState() => _SideNavBarState();
}
class _SideNavBarState extends State<SideNavBar> with SingleTickerProviderStateMixin{
int idx = 5;
double previousPosition = 825.0;
double _circleFraction = 0.0;
Animation<double> circleFraction;
AnimationController controller;
Animation curvedAnimation;
@override
void initState() {
controller = AnimationController(
duration: const Duration(milliseconds: 300), vsync: this
);
curvedAnimation = CurvedAnimation(parent: controller, curve: Curves.easeInOut);
super.initState();
}
_playAnimation(double pos) {
circleFraction = Tween(begin: previousPosition, end: pos).animate(curvedAnimation)
..addListener(() {
setState(() {
previousPosition = _circleFraction;
_circleFraction = circleFraction.value;
});
});
}
@override
Widget build(BuildContext context) {
return Material(
child: Container(
width: MediaQuery.of(context).size.width / 5,
color: Theme.of(context).primaryColor,
child: Stack(
children: <Widget>[CustomPaint(painter: CirclePainter(anim: _circleFraction == 0 ? previousPosition : _circleFraction, color: Theme.of(context).accentColor),), menuBar(),],
),
));
}
Widget menuBar() {
return Container(
width: MediaQuery.of(context).size.width / 7,
color: Theme.of(context).accentColor,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: GestureDetector(
onTap: () {
_playAnimation(115.0);
controller.forward(from: 0.0);
},
child: Icon(Icons.account_box, size: 32.0, color: Colors.black,)),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: GestureDetector(
onTap: () {
_playAnimation(180.0);
controller.forward(from: 0.0);
},
child: Icon(Icons.star, size: 32.0, color: Colors.black,)),
),
GestureDetector(
onTap: () {
_playAnimation(380.0);
controller.forward(from: 0.0);
},
child: Padding(
padding: const EdgeInsets.only(bottom: 32.0, top: 128.0),
child: RotatedBox(
quarterTurns: 3,
child: Text(
'Desserts',
style: stylingMedium(),
),
))),
GestureDetector(
onTap: () {
_playAnimation(530.0);
controller.forward(from: 0.0);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0),
child: RotatedBox(
quarterTurns: 3,
child: Text(
'Beverages',
style: stylingMedium(),
),
))),
GestureDetector(
onTap: () {
_playAnimation(685.0);
controller.forward(from: 0.0);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0),
child: RotatedBox(
quarterTurns: 3,
child: Text(
'Vegetarian',
style: stylingMedium(),
),
))),
GestureDetector(
onTap: () {
_playAnimation(825.0);
controller.forward(from: 0.0);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 32.0),
child: RotatedBox(
quarterTurns: 3,
child: Text(
'Combos',
style: stylingMedium(),
),
))),
],
),
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
class CirclePainter extends CustomPainter {
CirclePainter({this.anim, this.color});
final double anim;
final Color color;
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..style = PaintingStyle.fill
..color = color;
canvas.drawCircle(Offset(42, anim), 40.0, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
@override
bool shouldRebuildSemantics(CustomPainter oldDelegate) {
return true;
}
}
答案 0 :(得分:0)
您不能在getRange
之外拨打_playAnimation
。在Flutter I wrote a package that might be able to help中,在小部件之间传递状态是很痛苦的,只需确保阅读说明即可。
这里的主要问题是,您可以只全局定义_SideBarNavState
,但是您将无权访问_playAnimation
。我写了“查找”库来解决这个头疼的问题,但是人们也推荐Provider和BLOC。