まとまった情報とアクションを促すカードウィジェットを ListView と組み合わせて使う方法

カード (Card) はマテリアルデザインではコンテンツと、それに対する何らかのアクションのあるものを表示するために使われるものとされています。

例えば、写真を表示する場合、いまどき SNS っぽく Like という意思表示や、Share といったアクションを期待するのが普通ですよね。カードはそうした場合に使われます。

ここでは Card とリスト表示を組み合わせる例を示します。

ListView.builder はとても使いやすいウィジェットビルダーで、itemCount プロパティにリストの要素数を設定すると、 その数だけ itemBuilder に設定されたウィジェット構築用のファンクションが呼び出されるので、そこでリストの要素となるウィジェットを返します。

import 'package:flutter/material.dart';
import 'package:test18_card/picture_card.dart';

void main() => runApp(
      MaterialApp(
        debugShowCheckedModeBanner: false,
        home: MyApp(),
      ),
    );

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _State();
  }
}

class _State extends State<MyApp> {
  var _cardList = List<PictureCard>();

  @override
  void initState() {
    _cardList.add(PictureCard(
      'Torrance Beach',
      'The best beach in Torrance',
      'torrance-beach.jpg',
    ));
    _cardList.add(PictureCard(
      'Shake Shack',
      'American fast casual restaurant',
      'shake-shack.jpg',
    ));
    _cardList.add(PictureCard(
      'The Hat',
      'The best pastrami dip sandwich',
      'the-hat.jpg',
    ));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Card List Test'),
      ),
      body: Container(
        padding: EdgeInsets.all(8),
        child: ListView.builder(
          itemCount: _cardList.length,
          itemBuilder: (BuildContext context, int index) {
            return _cardList[index];
          },
        ),
      ),
    );
  }
}

ここで ListView.builderitemBuilder では、 PictureCard という自前のウィジェットのリストの要素を返しています。 picture_card.dart は次の通り。

import 'package:flutter/material.dart';

class PictureCard extends StatelessWidget {

  final String _name;
  final String _desc;
  final String _picture;

  PictureCard(this._name, this._desc, this._picture);

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          ListTile(
            leading: Icon(Icons.map),
            title: Text(_name),
            subtitle: Text(_desc),
          ),
          Image.asset('assets/$_picture'),
          ButtonTheme.bar(
            child: ButtonBar(
              children: <Widget>[
                FlatButton(
                  child: const Text('DIRECTION'),
                  onPressed: () {},
                ),
                FlatButton(
                  child: const Text('MAP'),
                  onPressed: () {},
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

画像はアセット用のフォルダに画像ファイルをおいた上で、pubspec.yaml にアセットを記述します。 詳しくは「画像の利用方法」をみてください。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Flutter 入門