Как правильно начать и закончить или анимацию и изменение текста из флаттера другого класса
Я изучаю флаттер, и я хочу начать анимацию и установить «синхронизацию» заголовка панели приложения из ответа AlertDialog (в основном из другого класса), затем завершить анимацию и снова установить заголовок после операции Async.
Итак, в настоящее время я добиваюсь этого с помощью GlobalKey и Riverpod (StateNotifier). Создал MainScreen GlobalKey и использовал этот GlobalKey из другого класса перед операцией Async, которую я вызываю
mainScreenScaffoldKey.currentState.context
.read(syncProgressProvider)
.setSyncing();
и завершение анимации после асинхронной операции:
mainScreenScaffoldKey.currentState.context
.read(syncProgressProvider)
.syncProgressDone();
код:
Map<String, dynamic> dialogResponse = await showDialog(
context: context,
builder: (context) => EditNoteScreen(
_index,
_task,
_color,
dateTime,
priority: priority,
));
if (dialogResponse != null) {
mainScreenScaffoldKey.currentState.context
.read(syncProgressProvider)
.setSyncing();
await SaveToLocal().save(context.read(listStateProvider.state));
await CloudNotes().updateCloudNote(
task: dialogResponse["task"],
priority: dialogResponse["priority"],
dateTime: dateTime.toString(),
index: dialogResponse["index"],
);
mainScreenScaffoldKey.currentState.context
.read(syncProgressProvider)
.syncProgressDone();
}
и переменная прослушивания в свойстве заголовка AppBar в MainScreen
Я считаю это неправильным подходом или нет?
вот несколько дополнительных фрагментов syncProgressProiver:
class SyncProgressModel extends StateNotifier<bool>{
SyncProgressModel() : super(false);
syncProgressDone(){
state =false;
}
setSyncing(){
state =true;
}
Заголовок панели приложений MainScreen
Consumer(
builder: (context, watch, child) {
var syncProgress = watch(syncProgressProvider.state);
if (!syncProgress) {
return const Text('To-Do List');
} else {
return Row(
children: [
const Text('Syncing..'),
Container(
margin: const EdgeInsets.only(left: 10),
width: 25,
height: 25,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: animColors,
),
)
],
);
}
},
),
Так
1 ответ
Я ничего не знаю о ваших анимациях (вы на самом деле не разделяете никакой этой логики или того, что вы имеете в виду 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
}
},
),