【Flutter】Card Widgetで立体的なレイアウトを簡単作成!【サンプルコードあり】

どうもyu_to(@yu_to_python)です。

今回はCard Widgetの実装方法について解説していきます。

Cardはアプリ内の要素を立体的に表示したい場合に積極的に利用されるWidgetです。

画像などと組み合わせる事で下のサンプルの様なよく見るカードの様なレイアウトを簡単に作成できます。

この記事を最後まで読めばCard Widgetの使い方が理解できますので是非最後まで読んでみてください。

Cardの特徴

コンパイル定数(const)を設定可能

よくCardと比較されるWidgetとしてContainerがありますが、CardはContainerと違い、コンパイル定数(const)を設定することができます。

コンパイル定数とは、Widgetのコンパイル時に1つだけインスタンスを生成して、何度同じ処理が実行されても最初に生成したインスタンスを使い回せる仕組みです。

これにより画面再描画時に無駄なインスタンス生成を防止できてアプリ全体のパフォーマンス改善に繋がります。

ただし、再描画の度にCardが持つ状態が変化する場合は定義できません。

(例として何かしらの変数の値を参照して描画している等)

もちろんconstを付けなくてもCardは使用可能です。

constを付けてWidgetを定義可能
~~~
// const(コンパイル定数)を定義できる
child: const Card(
  ...
),
~~~

立体的な表現を簡単に作成可能

Card Widget自体の影を調整可能なオプションがデフォルトで充実しているので簡単に立体的なレイアウトを作成できます。

もちろん影を消してフラットなレイアウトにするのも可能です。

サンプルコード

コピペですぐ動かせるのでまずは実際に動かしてみてください。

動作確認したバージョンは下記の通りです。

・Flutter 3.0.1

・Dart 2.13.3

main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Card',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Card'),
        ),
        body: Center(
          child: Column(
            children: [
              SizedBox(
                width: 300,
                height: 200,
                // const(コンパイル定数)を定義できる
                child: const Card(
                  child: Center(child: Text('Card1')),
                  color: Colors.green, // Cardの背景色
                  margin: const EdgeInsets.all(30), // Cardの外側の余白を設定するオプション
                  elevation: 8, // 影の離れ具合を調整するオプション
                  shadowColor: Colors.black, // 影の色を設定するオプション
                ),
              ),
              SizedBox(
                width: 300,
                height: 200,
                child: Card(
                  child: Center(child: Text('Card2')),
                  color: Colors.blue,
                  margin: const EdgeInsets.all(30),
                  elevation: 8,
                  shadowColor: Colors.red,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10),
                  ),
                ),
              ),
              SizedBox(
                width: 300,
                height: 200,
                child: Card(
                  margin: const EdgeInsets.all(30),
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(20),
                  ),
                  clipBehavior:
                      Clip.antiAliasWithSaveLayer, // Cardと被ったWidgetをCardの形に保持する
                  child: Row(
                    children: <Widget>[
                      Image.network(
                          'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTo7FLZVev8PvE4IK3-1evSjzC65pUQzCartw&usqp=CAU'),
                      Spacer(),
                      Text('ねこかわいい'),
                      Spacer(),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

よく使うオプション

color

Cardの背景色を設定できるオプション

example
~~~
color: Colors.green, // Cardの背景色
~~~

shadowColor

影の色を設定するオプション

example
~~~
shadowColor: Colors.black, // 影の色を設定するオプション
~~~

elevation

影の離れ具合を調整するオプション

example
~~~
elevation: 8, // 影の離れ具合を調整するオプション
~~~

shape

Cardの形を調整するオプション

example
~~~
shape: RoundedRectangleBorder(
  borderRadius: BorderRadius.circular(10),
),
~~~

margin

Cardの外側の余白を設定するオプション

example
~~~
margin: const EdgeInsets.all(30), // Cardの外側の余白を設定するオプション
~~~

clipBehavior

Cardと被ったWidgetをCardの形に保持するオプション。

このオプションを適用しないとCardの子Widgetに定義している画像が後ろのCardの形状にならず角がある状態になってしまう。

▼オプションなし

▼オプションあり

example
~~~
clipBehavior:
    Clip.antiAliasWithSaveLayer, // Cardと被ったWidgetをCardの形に保持する
~~~

child

Card内に設定する子Widgetを設定するオプション

example
~~~
child: Center(child: Text('Card1')),
~~~

tips

Card自体のサイズを変更したい

Cardの親WidgetにSizedBox Widgetを使用すると調整できます。

SizedBoxについてはこちらで個別に解説しているので参考にしてみてください。

【Flutter】Widgetのサイズを変更できるSizedBoxの使い方【サンプルコードあり】
example
~~~
SizedBox(
  width: 300,
  height: 200,
  child: const Card(
~~~

おわり

今回はCard Widgetの使い方を解説しました。

更に深堀りして仕様を知りたい方は公式ドキュメントを参照してみてください。

このブログでは他にもFlutterについての記事が上がっているので良ければそちらも参考にしてみてください。

【2022年最新】現役エンジニアがFlutter初学者向けおすすめ技術書3選を紹介!

【Flutter】SpacerでWidget間の空白を超簡単に最適化する

【Flutter】FVMで複数のSDKバージョンを簡単に切り替える