Contents
Create lists with different types of items
You might need to create lists that display different types of content. For example, you might be working on a list that shows a heading followed by a few items related to the heading, followed by another heading, and so on.
異なる種類のコンテンツを表示するリストを作成する必要がある場合があります。例えば、見出しの後にその見出しに関連するいくつかの項目を表示し、その後に別の見出しを表示する、といったリストを作成することがあります。
Here’s how you can create such a structure with Flutter:
下記のような方法で、Flutterでこのような構造を構築していきます。
- Create a data source with different types of items.
- Convert the data source into a list of widgets.
1. 異なるタイプのアイテムを持つデータソースを生成する。
2. データソースをウィジェットのリストに変換する。
1. Create a data source with different types of items
1.異なるタイプのアイテムを持つデータソースを生成する
Types of items
To represent different types of items in a list, define a class for each type of item.
リストの中の異なるタイプのアイテムを表すために、それぞれのタイプ用の三つのクラスを定義します。
三つは三つなのだが、一つは抽象クラス(ListItem)で、具体的なクラス(concrete classes)は二つ(HeadingItemとMessageItem)。
/// The base class for the different types of items the list can contain. /// リストが保持する異なるタイプのアイテムのベースクラス abstract class ListItem { /// The title line to show in a list item. /// リストのアイテムに表示するタイトルのウィジェット Widget buildTitle(BuildContext context); /// The subtitle line, if any, to show in a list item. /// 存在する場合にリストのアイテムに表示するサブタイトルのウィジェット Widget buildSubtitle(BuildContext context); } /// A ListItem that contains data to display a heading. /// 見出し(heading)を示すためのデータを保持するListItem class HeadingItem implements ListItem { final String heading; HeadingItem(this.heading); @override Widget buildTitle(BuildContext context) { return Text( heading, style: Theme.of(context).textTheme.headline5, ); } @override Widget buildSubtitle(BuildContext context) => const SizedBox.shrink(); } /// A ListItem that contains data to display a message. /// メッセージを示すためのデータを保持するListItem class MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body); @override Widget buildTitle(BuildContext context) => Text(sender); @override Widget buildSubtitle(BuildContext context) => Text(body); }
Create a list of items
Most of the time, you would fetch data from the internet or a local database and convert that data into a list of items.
ほとんどの場合、インターネットやローカルのデータベースからデータを取得し、そのデータを項目のリストに変換することになります。
For this example, generate a list of items to work with. The list contains a header followed by five messages. Each message has one of 3 types: ListItem
, HeadingItem
, or MessageItem
.
この例では、作業するアイテムのリストを生成します。このリストには、ヘッダーと5つのメッセージが含まれています。各メッセージは、3つのタイプのうちの1つを持っています。ListItem、HeadingItem、MessageItem のいずれかです。
実際はheadingItemとMessageItemのどちらかが表示されることになる。
final items = List<ListItem>.generate( 1000, (i) => i % 6 == 0 ? HeadingItem('Heading $i') : MessageItem('Sender $i', 'Message body $i'), );
2. Convert the data source into a list of widgets
To convert each item into a widget, use the ListView.builder()
constructor.
それぞれのアイテムをウィジェットに変換するために、ListView.builder()
コンストラクタを使います。
In general, provide a builder function that checks for what type of item you’re dealing with, and returns the appropriate widget for that type of item.
一般的には、どのような種類のアイテムを扱っているかをチェックし、その種類のアイテムに適したウィジェットを返すビルダー関数を提供します。
ListView.builder( // Let the ListView know how many items it needs to build. // ListViewに、ビルドすべきアイテムの数を知らせる。 itemCount: items.length, // Provide a builder function. This is where the magic happens. // ビルダー関数を提供する。これが肝となる箇所です。 // Convert each item into a widget based on the type of item it is. // それぞれのアイテムを、そのアイテムの種類に従ってウィジェットに変換する。 itemBuilder: (context, index) { final item = items[index]; return ListTile( title: item.buildTitle(context), subtitle: item.buildSubtitle(context), ); }, )
Interactive example
import 'package:flutter/material.dart'; void main() { runApp( MyApp( items: List<ListItem>.generate( 1000, (i) => i % 6 == 0 ? HeadingItem('Heading $i') : MessageItem('Sender $i', 'Message body $i'), ), ), ); } class MyApp extends StatelessWidget { final List<ListItem> items; const MyApp({super.key, required this.items}); @override Widget build(BuildContext context) { const title = 'Mixed List'; return MaterialApp( title: title, home: Scaffold( appBar: AppBar( title: const Text(title), ), body: ListView.builder( // Let the ListView know how many items it needs to build. itemCount: items.length, // Provide a builder function. This is where the magic happens. // Convert each item into a widget based on the type of item it is. itemBuilder: (context, index) { final item = items[index]; return ListTile( title: item.buildTitle(context), subtitle: item.buildSubtitle(context), ); }, ), ), ); } } /// The base class for the different types of items the list can contain. abstract class ListItem { /// The title line to show in a list item. Widget buildTitle(BuildContext context); /// The subtitle line, if any, to show in a list item. Widget buildSubtitle(BuildContext context); } /// A ListItem that contains data to display a heading. class HeadingItem implements ListItem { final String heading; HeadingItem(this.heading); @override Widget buildTitle(BuildContext context) { return Text( heading, style: Theme.of(context).textTheme.headline5, ); } @override Widget buildSubtitle(BuildContext context) => const SizedBox.shrink(); } /// A ListItem that contains data to display a message. class MessageItem implements ListItem { final String sender; final String body; MessageItem(this.sender, this.body); @override Widget buildTitle(BuildContext context) => Text(sender); @override Widget buildSubtitle(BuildContext context) => Text(body); }
参考