【Flutter】ListViewを使って配列をForループで画面にレンダリングしたい

Flutter
 

環境

macOS Big Sur Version 11.5.2

Flutter 2.2.3

XCode 12.5.1

実装概要

Javascriptのmap関数のような感じで、配列として持っている値を画面に描画する方法をまとめました。

ダメな実装

ソースコード

class _TodoState extends State<Todo> {
  final List<String> _todoList = ['HelloA,', 'HelloB', 'HelloC'];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hello Todo'),
      ),
      body: ListView(
        children: _todoList,
      ),
    );
  }

出力されたエラー

The argument type 'List<String>' can't be assigned to the parameter type 'List<Widget>'.da

ListViewにただ配列を入れ込んでも値は出力されません。

List<Widget>という値を返すような実装にしなければならないとのことでした。

正しい実装方法

_todoListにて定義されている配列の値をScaffoldのbody部分に定義されている_getItemsメソッドで描画します。

_getItemsメソッドにはString型の配列をWidget型に変える処理が記述されています。

からのWidget型の配列を作成し、forループにてStringの値をWidget配列にListTileとしてAddしています。

ソースコード

class _TodoState extends State<Todo> {
  final List<String> _todoList = ['HelloA,', 'HelloB', 'HelloC'];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hello Todo'),
      ),
      body: ListView(
        children: _getItems(),
      ),
    );
  }

  // iterates through our todo list titles.
  List<Widget> _getItems() {
    final List<Widget> _todoWidgets = <Widget>[];
    for (String title in _todoList) {
      _todoWidgets.add(
        ListTile(title: Text(title)),
      );
    }
    return _todoWidgets;
  }
}

上のようにWidgetを返すような関数を作成することでListViewを実装できます。

全体のソースコードはこちら

import 'package:flutter/material.dart';

void main() {
  runApp(const TodoContainer());
}

class TodoContainer extends StatelessWidget {
  const TodoContainer({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Todo(),
    );
  }
}

class Todo extends StatefulWidget {
  const Todo({Key? key}) : super(key: key);

  @override
  _TodoState createState() => _TodoState();
}

class _TodoState extends State<Todo> {
  final List<String> _todoList = ['HelloA,', 'HelloB', 'HelloC'];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Hello Todo'),
      ),
      body: ListView(
        children: _getItems(),
      ),
    );
  }

  // iterates through our todo list titles.
  List<Widget> _getItems() {
    final List<Widget> _todoWidgets = <Widget>[];
    for (String title in _todoList) {
      _todoWidgets.add(
        ListTile(title: Text(title)),
      );
    }
    return _todoWidgets;
  }

実装されたアプリ

コメント

タイトルとURLをコピーしました