画像のディレクトリパスを返す関数があります。ディレクトリが存在するかどうかなどの追加のチェックを実行し、それに応じて動作します。
これが私のコードです:
_Future<String> getImagesPath() async {
final Directory appDir = await getApplicationDocumentsDirectory();
final String appDirPath = appDir.path;
final String imgPath = appDirPath + '/data/images';
final imgDir = new Directory(imgPath);
bool dirExists = await imgDir.exists();
if (!dirExists) {
await new Directory(imgPath).create(recursive: true);
}
return imgPath;
}
_
このコードは期待どおりに機能しますが、Future
から値を取得する際に問題が発生します。
ケースシナリオ:ローカルデータベースにデータが保存されており、それをリストビュー内で表示しようとしています。この answer で説明されているように、私はFutureBuilder
を使用しています。各データ行には、イメージが関連付けられています(関連付けられているという意味で、イメージ名はdbに格納されています)。
_Widget build
_メソッド内に、次のコードがあります。
_@override
Widget build(BuildContext context) {
getImagesPath().then((path){
imagesPath = path;
print(imagesPath); //prints correct path
});
print(imagesPath); //prints null
return Scaffold(
//removed
body: FutureBuilder<List>(
future: databaseHelper.getList(),
initialData: List(),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, int position) {
final item = snapshot.data[position];
final image = "$imagesPath/${item.row[0]}.jpg";
return Card(
child: ListTile(
leading: Image.asset(image),
title: Text(item.row[1]),
subtitle: Text(item.row[2]),
trailing: Icon(Icons.launch),
));
})
: Center(
child: CircularProgressIndicator(),
);
}));
_
}
_.then
_内でのreturn Scaffold(.....)
のシフトは機能しません。ウィジェットのビルドは何も返さないからです。
私が見つけた他のオプションは_async/await
_ですが、最後に、同じ問題、以下のコードが利用可能です:
__getImagesPath() async {
return await imgPath();
}
_
_getImagesPath()
を呼び出すと、実際のデータではなくFuture
が返されます。
私は非常に小さな論理的な間違いがあると思いますが、それを自分で見つけることはできません。
このコードをFutureBuilder
内に移動すると、問題が解決します。
getImagesPath().then((path){
imagesPath = path;
print(imagesPath); //prints correct path
});
したがって、最終的なコードは次のようになります。
@override
Widget build(BuildContext context) {
return Scaffold(
//removed
body: FutureBuilder<List>(
future: databaseHelper.getList(),
initialData: List(),
builder: (context, snapshot) {
return snapshot.hasData
? ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, int position) {
getImagesPath().then((path){
imagesPath = path;
});
final item = snapshot.data[position];
final image = "$imagesPath/${item.row[0]}.jpg";
return Card(
child: ListTile(
leading: Image.file(File(image)),
title: Text(item.row[1]),
subtitle: Text(item.row[2]),
trailing: Icon(Icons.launch),
));
})
: Center(
child: CircularProgressIndicator(),
);
}));
}
それが役に立てば幸い!