gpt4 book ai didi

flutter - 我如何从外部小部件访问内部小部件的动画 Controller (或状态)?

转载 作者:IT王子 更新时间:2023-10-29 07:07:03 24 4
gpt4 key购买 nike

因此,过去几天我一直在尝试使用 Flutter & Dart。我已经在这个问题上停留了一天多了,所以我来了。

所以我有 AlarmScreen,里面有 2 个对象。一个是 DraggableMoonWidget,另一个是 RisingSunWidget

目前,RisingSunWidget 从底部动画到屏幕上,而 DraggableMoonWidget 可通过触摸拖动。

我想要实现的是,当 RisingSunWidget 的 动画停止并在拖动 DraggableMoonWidget 时发生变化。所以我有 MoonDragListener 就位并且可以正常工作,但我仍然无法弄清楚。 (当前将监听器调用回 AlarmScreen,但之后呢?)

我已经尝试了一大堆方法来做到这一点,从那以后所有方法都被删除了,因为没有一个有效。

长短不一如何在用户触摸 DraggableMoonWidget 时控制 RisingSunWidget 的 动画 Controller ,例如,我想停止 Controller 并将其动画化到不同的点。

dart/flutter 中最好的方法是什么?

警报屏幕

import 'package:flutter/widgets.dart';
import 'package:moonworshiper_app/backgrounds.dart';
import 'package:moonworshiper_app/ui/alarm/moon_draggable.dart';
import 'package:moonworshiper_app/ui/alarm/rising_sun.dart';

class AlarmScreen extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _AlarmScreenState();
}
}

class _AlarmScreenState extends State<AlarmScreen> {
bool _moonWasTouched = false;

@override
void initState() {
super.initState();
}

@override
Widget build(BuildContext context) {
return new Stack(
children: <Widget>[
new DraggableMoonWidget(new MoonDragListener(this)),
new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new RisingSunWidget(constraints.heightConstraints().maxHeight, _moonWasTouched);
})
],
);
}

void _refreshSun() {
setState(() {
_moonWasTouched = true;
});
}
}

class MoonDragListener {
_AlarmScreenState state;

MoonDragListener(this.state);

void onMoonDragStarted() {
state._refreshSun();
}
}

DraggableMoonWidget

import 'package:flutter/widgets.dart';
import 'package:moonworshiper_app/ui/alarm/alarm_screen.dart';

class DraggableMoonWidget extends StatefulWidget {

final MoonDragListener moonStartListener;

DraggableMoonWidget(this.moonStartListener);

State<StatefulWidget> createState() => new _DraggableMoonState();
}

class _DraggableMoonState extends State<DraggableMoonWidget>
with TickerProviderStateMixin {


final moonDragTween = new Tween<Offset>(
begin: new Offset(0.0, -0.5),
end: new Offset(0.0, 0.5),
);

var moonAnimListener;
AnimationController _animationController;
Animation<Offset> _dragAnimation;
AnimationController _dragAnimationController;
bool isFirstDraw = true;

@override
initState() {
super.initState();
_animationController = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 3000),
);
_dragAnimationController = new AnimationController(vsync: this);

moonAnimListener = (AnimationStatus status) {
if (status == AnimationStatus.dismissed) {
_animationController.forward();
} else if (status == AnimationStatus.completed) {
_animationController.reverse();
} else if (status == AnimationStatus.forward) {}
};

_dragAnimation = moonDragTween.animate(new CurvedAnimation(
parent: _dragAnimationController,
curve: Curves.easeInOut,
reverseCurve: Curves.easeInOut));

_dragAnimationController.animateTo(0.5, duration: new Duration());


_animationController.addStatusListener(moonAnimListener);


_animationController.forward();
}

@override
Widget build(BuildContext context) {
return new Container(
child: new Center(
child: new SlideTransition(
position: _dragAnimation,
child: new GestureDetector(
child: new Image.asset(
"assets/moon.png",
width: 280.0,
height: 280.0,
),
onVerticalDragStart: (DragStartDetails details) {
print("start:" + details.globalPosition.toString());
_animationController.removeStatusListener(moonAnimListener);
_animationController.stop();
_dragStartDetails = details;

_dragAnimationController.animateTo(0.5,
duration: new Duration(milliseconds: 50));

if (isFirstDraw) {
isFirstDraw = false;
widget.moonStartListener.onMoonDragStarted();
}
},
),
),
),
// margin: new EdgeInsets.only(top: 48.0),
);
}

@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}

RisingSunWidget

import 'package:flutter/widgets.dart';

class RisingSunWidget extends StatefulWidget {
// needed to calculate the offset map
final double screenHeight;

// that's how we know if the use touched the moon
final bool moonWasTouched;

RisingSunWidget(this.screenHeight, this.moonWasTouched);

@override
State<StatefulWidget> createState() {
return new RisingSunState();
}
}

class RisingSunState extends State<RisingSunWidget> with TickerProviderStateMixin {
AnimationController _animationController;
Animation<Offset> _sunAnimation;

final double sunSize = 320.0;

@override
initState() {
super.initState();

_animationController = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 6000),
);

// how many suns fit in the height of our screen

assert(widget.screenHeight > sunSize);

double sunsInHeight = widget.screenHeight / sunSize;

print(sunsInHeight.toString() + " suns could fit on the user's screen");

var sunsPlusMargins = sunsInHeight + 1; // required margins

final moonTween = new Tween<Offset>(
begin: new Offset(0.0, -0.5 * sunsPlusMargins),
end: new Offset(0.0, 0.5 * sunsPlusMargins), //move by 8% of height max
);

_sunAnimation = moonTween.animate(new CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
reverseCurve: Curves.easeInOut,
));


if (widget.moonWasTouched) {
_animationController.stop();
_animationController.animateTo(0.68,
duration: new Duration(milliseconds: 2000));
} else {
_animationController.animateTo(0.88,
duration: new Duration(milliseconds: 0));
_animationController.animateTo(0.75,
duration: new Duration(milliseconds: 15000));
}
}

@override
Widget build(BuildContext context) {
return new Center(
child: new SlideTransition(
position: _sunAnimation,
child: new Image.asset(
"assets/sun.png",
width: sunSize,
height: sunSize,
),
),
);
}

@override
void dispose() {
_animationController.dispose();
super.dispose();
}


}

最佳答案

2 种可能性:

  • 使用构建方法中提供的 BuildContext 上下文BuildContext 有几个方法可以获取特定类型的最近父级。
  • key 属性传递给所需的小部件。GlobalKey 确切地说。GlobalKey 允许您直接访问 Widget 或其状态。

关于flutter - 我如何从外部小部件访问内部小部件的动画 Controller (或状态)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47034227/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com