私のアプリでは、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");
},
),
],
);
}
}