В своем приложении я использую riverpod и flutter_tts, чтобы прочитать вслух HTTP-ответ. Во-первых, я добавил его после получения данных в FutureProvider следующим образом:
final futureProvider = FutureProvider.family<String, String>((ref, itemId) async {
// fetch data from server
final result = await Future.delayed(Duration(seconds: 1)).then((value) => "$itemId");
await SpeakResult(result); // speak here
return result;
});
но он был прочитан вслух ТОЛЬКО в первый раз, даже если FutureProvider вызывался несколько раз с одним и тем же itemId.
Во-вторых, я добавил его в метод build
, но он ВСЕГДА читался вслух при пересборке виджета.
useProvider(futureProvider("item id")).when(
loading: () => CircularProgressIndicator(),
error: (error, stackTrace) => Text("$error"),
data: (value) async {
await SpeakResult(value);
return Text("$value");
},
);
Есть идея решить это?
Полный код здесь:
final futureProvider = FutureProvider.autoDispose.family<String, String>((ref, id) async {
ref.onDispose(() => print("disposed"));
// fetch data from server
final result = Future.delayed(Duration(seconds: 1)).then((value) => "$id");
// await SpeakResult(result);
return result;
});
final asyncListProvider = StateNotifierProvider((_) => AsyncList());
class AsyncList extends StateNotifier<List<AutoDisposeFutureProvider<String>>> {
AsyncList() : super([]);
void add(String id) {
/*
//I want to do something like this:
final asyncValue = futureProvider(id).whenData((value) async {
await SpeakResult(result);
return value;
});
*/
final asyncValue = futureProvider(id);
state = [asyncValue, ...state];
}
}
class MyHomePage extends HookWidget {
const MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final list = useProvider(asyncListProvider.state);
return ListView(
children: [
RaisedButton(
child: Text("Add data"),
onPressed: () {
context.read(asyncListProvider).add("item id");
},
),
for (final item in list)
useProvider(item).when(
loading: () => ListTile(
title: Center(child: CircularProgressIndicator()),
),
error: (error, stackTrace) => Text("$error"),
data: (value) {
// await SpeakResult(value);
return Text("$value");
},
),
],
);
}
}