FlutterのCardウィジェットを理解する:使い方から実務での活用まで

モバイル開発

はじめに

Flutterでは、見た目を整えつつ操作しやすいUIパーツが豊富に用意されています。 その中でもCardウィジェットは、情報を区切ってわかりやすく表示したいときに役立ちます。

一見シンプルな見た目ですが、画像やテキスト、ボタンなどを自由に配置できるため、多くのアプリで採用されています。 本記事ではCardウィジェットの基本的な使い方から、複数のカードを一覧で並べる例などを取り上げます。

初心者の方でも理解しやすいように、具体的なコード例を交えながら解説していきます。 ぜひ読んでみて、カード形式のUIを作るときのイメージをつかんでみてください。

この記事を読むとわかること

  • FlutterのCardウィジェットの基礎知識と役割
  • カードを実際に作成するときの具体的なコード例
  • 実務での活用シーンや注意点

FlutterのCardとは

Cardウィジェットは、立体感のある紙のような見た目を作り出すために用いられます。 境界や影を付与しやすく、1つの情報ブロックとして区切りを明確にすることができます。

また、Cardウィジェット自体はシンプルなので、コンテンツのレイアウトは内部で自由に組むことができます。 テキストや画像を組み合わせることにより、わかりやすい情報表示が可能です。

使い方としては、Cardウィジェットを親要素にして、その中にColumnやRowなどを配置していきます。 この仕組みによって、複数の情報をまとめて表示できるのです。

Cardが多用されるシーン

多くのアプリでは、リスト形式で商品や記事を並べることがあります。 例えばECサイトのアプリ画面でも、一つひとつのカードが商品情報を示す例がよく見られます。

また、SNS系アプリやニュースアプリなどでも、記事一覧や投稿一覧をカードで表示するケースがあります。 一つひとつの投稿を独立したブロックとみなすことで、区切りがわかりやすくなるからです。

加えて、プロフィールカードやユーザーレビューなどの表示にも向いています。 カード自体が独立したデザインになるため、背景と要素をはっきり分けられます。

Cardの基本構造を理解する

Cardウィジェットは、主に以下のようなプロパティで見た目を調整します。 要素を入れる際には子ウィジェットとしてColumnやRow、Containerなどを配置する流れになります。

  • child: Cardの中身となるウィジェットを指定
  • margin: カードの余白
  • elevation: カードの影の大きさ
  • shape: カードの角の丸みや形

これらを組み合わせるだけでも、シンプルなカードを作ることができます。 次のセクションでは、まず最初のコード例を見ていきましょう。

基本的なCardの実装例

下記のサンプルでは、カードの中にテキストを配置する簡単な例を示しています。

import 'package:flutter/material.dart';

class SimpleCardExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Simple Card Example'),
        ),
        body: Center(
          child: Card(
            elevation: 4, // 影の度合い
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8),
            ),
            child: Padding(
              padding: EdgeInsets.all(16),
              child: Text(
                'これはシンプルなCardの例です。',
                style: TextStyle(fontSize: 18),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

このサンプルではCardウィジェットのchildPaddingを入れ、その中にテキストを表示しています。 elevationを指定することで影を付与し、shapeで角を丸めています。

paddingはカード内の余白を設定するために使われます。 これだけでもカードらしい見た目が作れますし、さらに要素を追加すれば情報量を増やすことが可能です。

複数のCardを一覧表示する

実際のアプリでは、カードを1つだけでなく複数個並べて表示したい場面が多いです。 一覧表示をするときには、ListViewやGridViewを使用することが多いでしょう。

下記の例では、複数のCardを縦方向に一覧として表示します。 商品リストやユーザー投稿の一覧などのイメージで考えてください。

import 'package:flutter/material.dart';

class CardListExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final items = [
      'カード1の情報',
      'カード2の情報',
      'カード3の情報',
      'カード4の情報',
    ];

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Card List Example'),
        ),
        body: ListView.builder(
          itemCount: items.length,
          itemBuilder: (context, index) {
            return Card(
              elevation: 2,
              margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
              child: ListTile(
                title: Text(items[index]),
                subtitle: Text('サブタイトル情報'),
                leading: Icon(Icons.label),
                trailing: Icon(Icons.arrow_forward),
              ),
            );
          },
        ),
      ),
    );
  }
}

ここではListView.builderを使って、配列itemsの内容を順番にCardとして描画しています。 ListTileウィジェットをCardの中に入れることで、リストアイテムっぽいレイアウトを簡単に構築できます。

縦に並んだカードは、タイトルやアイコンを並べることで情報をわかりやすく区切っています。 これをさらに拡張して、ネットから取得したデータや画像を載せることもできます。

カードの見た目をさらにカスタマイズする

Cardウィジェットは初期設定のままでも十分使いやすいですが、もう少し見た目を変えたい場合もあります。 テキストだけでなく、画像やボタンを並べて情報をリッチにすることが可能です。

以下では、画像とボタンを配置してみる例を示します。 カードの中にColumnを使うことで上下にウィジェットを配置しています。

import 'package:flutter/material.dart';

class CustomCardExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Custom Card Example'),
        ),
        body: Center(
          child: Card(
            elevation: 3,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(12),
            ),
            margin: EdgeInsets.all(16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Image.network(
                  'https://via.placeholder.com/400',
                  fit: BoxFit.cover,
                ),
                Padding(
                  padding: EdgeInsets.all(16),
                  child: Text(
                    'Cardに画像とテキストを入れました。',
                    style: TextStyle(fontSize: 16),
                  ),
                ),
                ButtonBar(
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        // ボタンが押された時の処理
                      },
                      child: Text('アクション1'),
                    ),
                    OutlinedButton(
                      onPressed: () {
                        // ボタンが押された時の処理
                      },
                      child: Text('アクション2'),
                    ),
                  ],
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Columnを使うことで、画像 -> テキスト -> ボタン といった流れを縦方向に配置できます。 画像を横幅に合わせて表示したい場合は、BoxFit.coverを利用すると便利です。

ButtonBarを利用することで、複数のボタンを横並びに配置できます。 アクションボタンを付けると、情報提供だけでなくユーザー操作を促すUIにも活用できます。

実務での利用におけるヒント

プロトタイプの段階や学習中であれば、Cardのデザインはそれほど複雑にならないかもしれません。 しかし、実際のアプリ開発では、見た目を調整しつつ多様な機能を載せるケースが多くなります。

たとえば、ユーザーのプロフィールをカードで表示し、その下にフォローボタンやメッセージ送信ボタンを置くことがあります。 カード1枚につき複数のUI要素があると、縦や横のスペース配置がポイントになってきます。

また、カードをタップしたときに詳細画面へ遷移するなどのアクションを加える場面も多いです。 その場合、InkWellGestureDetectorと組み合わせることでタップに反応するカードを作ることができます。

カードの背景色や角の丸み、枠線などをカスタマイズするだけでも雰囲気が変わります。 「丸みを大きくして柔らかいイメージにする」「角をしっかりさせてシャープな印象にする」など、デザインに合わせて調整してみると良いでしょう。

Cardをタップ可能にする例

次の例では、InkWellを使ってカード自体がタップできるイメージを作っています。 タップ時にアプリバーに表示されるテキストを変化させる仕組みを簡単に入れてみました。

import 'package:flutter/material.dart';

class TappableCardExample extends StatefulWidget {
  
  _TappableCardExampleState createState() => _TappableCardExampleState();
}

class _TappableCardExampleState extends State<TappableCardExample> {
  String appBarTitle = 'Tappable Card Example';

  void _onCardTapped() {
    setState(() {
      appBarTitle = 'Cardがタップされました';
    });
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(appBarTitle),
        ),
        body: Center(
          child: InkWell(
            onTap: _onCardTapped,
            child: Card(
              elevation: 3,
              margin: EdgeInsets.all(16),
              child: Padding(
                padding: EdgeInsets.all(20),
                child: Text(
                  'このCardをタップできます。',
                  style: TextStyle(fontSize: 18),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

InkWellで囲むことで、タップ検知だけでなくタップ時の水面効果(インクエフェクト)も付けやすくなります。 このようにしてカードにアクションを持たせれば、リストから詳細ページへスムーズに遷移するUIを作ることができます。

アニメーション付きCardの活用

Cardウィジェットをさらに工夫して、アニメーションを加えることもよくあります。 画面遷移時にカードが拡大するような演出を行うと、視覚的に魅力的です。

ただ、初心者の方が最初からアニメーションを入れようとすると、仕組みが少し難しく感じるかもしれません。 初めはシンプルな表示・非表示やスライドアニメーションなどから始めると理解しやすいでしょう。

アニメーション関連で一般的に使われるのはAnimatedContainerHeroウィジェットなどです。 カードでコンテンツをまとめながら、より見た目に工夫を加えたい場合には挑戦してみると面白いです。

実務シーンで想定される課題

プロジェクトが大きくなると、一覧表示のカード数が増える可能性があります。 膨大な数のカードを作成すると、画面描画が重く感じられることがあります。

その場合は、ListView.builderGridView.builderのようなビルダー系ウィジェットを使うなど、レンダリングの最適化を検討すると良いでしょう。 また、スクロール時のパフォーマンスにも注意し、画像のプリロードやキャッシュ管理などを行うことが大切です。

もう一つ考えられるのは、カード内部の状態管理です。 ユーザーがいいねを押したり、チェックを入れたりするような機能がある場合、StatefulWidgetとの組み合わせ方に工夫が必要です。

カードを無闇にネストしすぎると、可読性やメンテナンス性が下がる可能性があります。 複雑になりそうな場合は小さなウィジェットに分割し、部品単位で管理をすることを検討すると良いでしょう。

Cardのデザインを統一する方法

アプリ全体で使うCardのデザインを統一したい場合は、ThemeThemeDataを使う方法があります。 theme: ThemeData(...)の中でCardThemeを設定すると、アプリ全体で共通のカードスタイルを適用できます。

複数の画面にまたがって統一感を出したいときに、この方法は便利です。 一方で、一部の画面だけ個別のデザインにしたいときは、ウィジェット単位でスタイルをオーバーライドすることもできます。

また、カードのサイズを揃えたいケースでは、親ウィジェットのレイアウトに合わせてSizedBoxを使う方法もあります。 一覧で並べたときに整然と見せたい場合は、幅や高さを固定して配置を調整するといいでしょう。

シンプルなコード例で学び、必要に応じて拡張する

はじめのうちは、1つのCardを作り、そこに少しずつ要素を追加していくのが理解しやすいです。 テキストや画像、ボタンなどを加えながら、「このパーツはどこに配置するのが最適か」を確かめてみてください。

実際にアプリを作り始めると、「もっと余白を増やしたい」「背景を透過色にしたい」といった要求が出てくると思います。 カード周辺のウィジェットを工夫して調整するうちに、自然とUIに関する知識が身についてきます。

最終的には、必要な機能が追加されて複雑な画面になることもありますが、Cardをベースにしてブロック構造を組んでおくと、管理がしやすいです。

まとめ

FlutterのCardウィジェットは、アプリ内で情報をグルーピングして表示するときに便利な機能です。 テキストや画像などを自由にレイアウトでき、影や角丸などで視覚的に境界を作れる点が特徴になります。

複数のカードを並べて一覧表示を作りたいときや、タップ可能なカードで詳細画面へ誘導したいときなど、多くのシーンで活用が期待できます。 また、アプリ全体でカードのスタイルを統一すれば、デザインに一貫性を持たせられます。

ぜひシンプルな例から始め、徐々にカスタマイズを加えて慣れていってみてください。 カードのデザインが決まると、アプリの見やすさや使いやすさが大きく変わるでしょう。

Flutterをマスターしよう

この記事で学んだFlutterの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。