我对您的动画一无所知(您实际上并没有共享任何逻辑或您指的是什么 initState)但是如果您唯一想要的就是为 CircularProgressIndicator 的颜色设置动画,那么您可以创建StatefulWidget
一个为您执行此操作并仅在以下情况下调用它来构建syncProgress == true
class AnimatedWidget extends StatefulWidget {
AnimatedWidget({Key key}) : super(key: key);
@override
_AnimatedWidgetState createState() => _AnimatedWidgetState();
}
class _AnimatedWidgetState extends State<AnimatedWidget>
with SingleTickerProviderStateMixin {
AnimationController _controller;
final Animatable<Color> _colorTween = TweenSequence<Color>([
TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.red, end: Colors.amber),
weight: 20,
),
TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.amber, end: Colors.green),
weight: 20,
),
TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.green, end: Colors.blue),
weight: 20,
),
TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.blue, end: Colors.purple),
weight: 20,
),
TweenSequenceItem<Color>(
tween: ColorTween(begin: Colors.purple, end: Colors.red),
weight: 20,
),
]).chain(CurveTween(curve: Curves.linear));
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 5),
animationBehavior: AnimationBehavior.preserve,
vsync: this,
)..repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
const Text('Syncing..'),
Container(
margin: const EdgeInsets.only(left: 10),
width: 25,
height: 25,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: _colorTween.animate(_controller)
),
)
],
);
}
}
在你的消费者中调用它,小部件将自己处理动画
Consumer(
builder: (context, watch, child) {
var syncProgress = watch(syncProgressProvider.state);
if (!syncProgress) {
return const Text('To-Do List');
} else {
return AnimatedWidget(); //right here
}
},
),
更新
要在其 dispose() 方法中安全地引用小部件的祖先,请通过在小部件的 didChangeDependencies() 方法中调用dependOnInheritedWidgetOfExactType() 来保存对祖先的引用。
这意味着在重建上下文本身之前,您应该根据您的上下文保留对象的引用(当您在对话框中调用 updateValueAt 或 updateValue 时,它会重建列表并且调用 context.read 不再安全)
updateCloudNote(BuildContext context) async {
/// keep the reference before calling the dialog to prevent
/// when the context change because of the dialogs action
final syncProgress = context.read(syncProgressProvider);
final listState = context.read(listStateProvider.state);
Map<String, dynamic> dialogResponse = await showDialog(
context: context,
builder: (context) => EditNoteScreen(
_index,
_task,
_color,
dateTime,
priority: priority,
));
if (dialogResponse != null) {
//when using GlobalKey didn't get that Widget Ancestor error
// use the reference saved instead of context.read
syncProgress.setSyncing();
await SaveToLocal().save(listState);
await CloudNotes().updateCloudNote(
task: dialogResponse["task"],
priority: dialogResponse["priority"],
dateTime: dateTime.toString(),
index: dialogResponse["index"],
);
syncProgress.syncProgressDone();
}
}
你结合提供者所做的基本上就是你可以在同一内部做的事情syncProgressProvider
final syncProgressProvider = StateNotifierProvider<SyncProgressModel>((ref)
=> SyncProgressModel(ref.read));
class SyncProgressModel extends StateNotifier<bool>{
final saveToLocal saveLocal = SaveToLocal();
final CloudNotes cloudNotes = CloudNotes();
final Reader _read;
SyncProgressModel(this._read) : super(false);
syncProgressDone(){
state = false;
}
setSyncing(){
state = true;
}
updateCall({int priority, int index, String task, String dateTime}) async {
state = true;
await saveLocal.save(_read(listStateProvider.state));
await cloudNotes.updateCloudNote(
task: task,
priority: priority,
dateTime: dateTime,
index: index,
);
state = false;
}
}
最后结合两个想法:
updateCloudNote(BuildContext context) async {
/// keep the reference before calling the dialog to prevent
/// when the context change because of the dialogs action
final syncProgress = context.read(syncProgressProvider);
Map<String, dynamic> dialogResponse = await showDialog(
context: context,
builder: (context) => EditNoteScreen(
_index,
_task,
_color,
dateTime,
priority: priority,
));
if (dialogResponse != null) {
await syncProgress.updateCall(
task: dialogResponse["task"],
priority: dialogResponse["priority"],
dateTime: dateTime.toString(),
index: dialogResponse["index"],
);
}
}