質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

1回答

267閲覧

Flutter(Dart)で画像をグリッド表示したいのですが、for...inでエラーになり、forEachに変更してもエラー。

Akira4989

総合スコア1

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

foreach

foreachは、List・Collection・Arrayといったデータ構造の各要素に対して繰り返し処理を実行するために扱われる、制御構造の構文です。

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2023/11/16 02:24

初めて投稿します。
Flutter(Dart)を始めて3日目になります。

実現したいこと

スマホアプリでアプリ内に保存しているjpg画像をInstagramのようにグリッド表示し、タップされた画像を画面に合わせて表示できるようにしたいと考えています。

直したいこと

Android Studioを使ってFlutter(Dart)で上記のようなアプリを作ってみたく、見よう見まねでコードを書いてみたのですが、下記のエラーが消えず悩んでいます。

発生している問題・エラーメッセージ

コーディングしているエリアの右上のエラーとワーニングの数が表示されているところを押してみると、ソースの下に下記の3つのエラーが出ます。

Function expressions can't be named. :23 Expected an identifier. :23 The getter '(' isn't defined for the type 'Future<List<String>>'. :23

デバッグボタンを押して実行してみると下記のエラーになります。

lib/griddisplay_images.dart:23:26: Error: A function expression can't have a name. fileNameList.forEach(imageFileName) { ^^^^^^^ lib/griddisplay_images.dart:23:26: Error: Expected an identifier, but got 'forEach'. Try inserting an identifier before 'forEach'. fileNameList.forEach(imageFileName) { ^^^^^^^ Target kernel_snapshot failed: Exception FAILURE: Build failed with an exception.

該当のソースコード

Flutter(Dart)

1import 'dart:io'; 2 3import 'package:flutter/material.dart'; 4 5class GridImagesPage extends StatelessWidget { 6 const GridImagesPage({ 7 Key? key, 8 }) : super(key: key); 9 10 @override 11 Widget build(BuildContext context) { 12 Future<List<String>> fileNameList = getFileList(); 13 return Scaffold( 14 appBar: AppBar( 15 title: const Text('画像をタップしてください'), 16 ), 17 body: GridView.count( 18 crossAxisCount: 3, 19 childAspectRatio: 1.5, 20 mainAxisSpacing: 4, 21 crossAxisSpacing: 4, 22 children: [ 23 fileNameList.forEach(imageFileName) { 24 //for (var imageFileName in fileNameList) 25 Hero( 26 tag: Text(imageFileName), 27 child: GestureDetector( 28 onTap: () { 29 Navigator.of(context).push( 30 MaterialPageRoute<void>( 31 builder: (context) => 32 ImagePage( 33 imageFile: imageFileName, 34 ), 35 ), 36 ); 37 }, 38 ), 39 ); 40 } 41 ]), 42 ); 43 } 44 45 Future<List<String>> getFileList() async { 46 Directory imageFileDir = Directory('images/'); 47 List<String> fileNameList = []; 48 await for (var entity 49 in imageFileDir.list(recursive: false, followLinks: false)) { 50 fileNameList.add(entity.path); 51 } 52 return fileNameList; 53 } 54} 55 56class ImagePage extends StatelessWidget { 57 const ImagePage({ 58 required this.imageFile, 59 Key? key, 60 }) : super(key: key); 61 final String imageFile; 62 63 @override 64 Widget build(BuildContext context) { 65 return Material( 66 child: Scaffold( 67 backgroundColor: Colors.black87, 68 appBar: AppBar( 69 title: Text(imageFile), 70 leading: BackButton( 71 color: Colors.white, 72 ), 73 ), 74 body: Padding( 75 padding: const EdgeInsets.symmetric(horizontal: 16), 76 child: Hero( 77 tag: Text(imageFile), 78 child: Center(child: Image.asset(imageFile)), 79 ), 80 ), 81 ), 82 ); 83 } 84}

試したこと

元々は、24行目にコメントアウトしていますが、for...inでループさせようとしたのですが、下記のエラーが出て色々と調べていたところforEachでのループを試して見ることにしました。

for...inでのエラー

1The type 'Future<List<String>>' used in the 'for' loop must implement 'Iterable'.` :24

補足情報(FW/ツールのバージョンなど)

Android Studio Giraffe | 2022.3.1 Patch 3
Flutter 3.13.9

対処方法がお分かりになられる方がいりゃっしゃいましたら何卒お教えいただけますようお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

buildの中でFutureなデータを取り扱う場合はFutureBuilderを使うのが一般的です。
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

GridViewをFutureBuilderでラッピングして、FutureBuilderのfutureにfileNameListを指定してFuture処理が完了したらGridViewをビルドするようにするのが、まず第一にすること。
これで、GridViewに渡すデータをFuture<List<String>>からList<String>にすることができる。

次の点は、forEachを使っているところ。
ここが実際にエラーとして出力されている場所。

forEachはリターンがvoidなので[]内では使えません。
childrenはList<Widget>なので、[]の中に入れる場合はWidgetを返すコードにしないといけない。

ただ今回はList<String>からList<Hero>なものを作ろうとしているので、以下の様にmap経由にするのが良いと思う。

dart

1child : fileNameList.map((imageFileName) { 2 //for (var imageFileName in fileNameList) 3 return Hero( 4 tag: Text(imageFileName), 5 child: GestureDetector( 6 onTap: () { 7 Navigator.of(context).push( 8 MaterialPageRoute<void>( 9 builder: (context) => ImagePage( 10 imageFile: imageFileName, 11 ), 12 ), 13 ); 14 }, 15 ), 16 ); 17 }).toList())

fileNameListは元のコードではFuture<List<String>>だけど上の実装ではList<String>になった物として取り扱ってます。

投稿2023/11/16 09:43

ta.fu

総合スコア1662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Akira4989

2023/11/17 00:45

アドバイスいただきありがとうございます。l 確かに型が違えば受け取れないですね。 調べている時にFutureBuilderはよく目にしましたので、その方法の方が一般的なのですね。 ソースも手直ししていただき、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問