🔷

【Flutter】Cardデザイン集

2023/09/03に公開

はじめに

FlutterのCardの見た目をしたデザイン集(サンプル集)を作りました。
主にCardウィジェットを使用したものになります。
よかったらコピペして使ってください。
(随時更新していきます。)

横長カードデザイン

デザイン①

card_1.dart
Card(
  elevation: 4,
  margin: const EdgeInsets.all(16),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(16),
  ),
  clipBehavior: Clip.antiAliasWithSaveLayer, // 画像を丸角にする
  child: Column(
    children: [
      Stack(
        children: [
          SizedBox(
            width: double.infinity,
            height: 200,
            child: Image.network(
              'https://source.unsplash.com/300x200/?resort',
              fit: BoxFit.cover,
            ),
          ),
          // ハートアイコン
          Positioned(
            top: 16,
            right: 16,
            child: IconButton(
              icon: const Icon(
                Icons.favorite_outline,
                color: Colors.white,
              ),
              iconSize: 28,
              padding: EdgeInsets.zero,
              constraints:
                  const BoxConstraints(), // アイコンボタンの余白を0にするため記述
              onPressed: () {},
            ),
          ),
        ],
      ),
      // タイトル
      Container(
        width: double.infinity,
        padding:
            const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
        child: const Text(
          'タイトル',
          style: TextStyle(
            fontWeight: FontWeight.w600,
            fontSize: 22,
          ),
        ),
      ),
      // 説明文
      Container(
        width: double.infinity,
        padding: const EdgeInsets.symmetric(horizontal: 8),
        child: const Text(
          'ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。',
          style: TextStyle(
            color: Colors.grey,
            fontSize: 16,
          ),
        ),
      ),
    ],
  ),
)

デザイン②

card_2.dart
Card(
  elevation: 0,
  margin: const EdgeInsets.all(16),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(8),
  ),
  child: Stack(
    children: [
      // 商品画像
      Container(
        width: double.infinity,
        height: 260,
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(8),
          image: const DecorationImage(
            image: NetworkImage(
                'https://source.unsplash.com/300x200/?tree'),
            fit: BoxFit.cover,
          ),
        ),
      ),
      Positioned(
        bottom: 0,
        left: 0,
        right: 0,
	// オーバーレイ
        child: Container(
          color: Colors.grey.withOpacity(0.5),
          padding: const EdgeInsets.all(4),
          height: 96,
          child: const Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'タイトル',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w600,
                  fontSize: 22,
                ),
              ),
              Text(
                'ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。',
		maxLines: 2,
                overflow: TextOverflow.ellipsis,
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 16,
                ),
              ),
            ],
          ),
        ),
      ),
    ],
  ),
),

デザイン③

card_3.dart
SizedBox(
  height: 230,
  child: Stack(
    children: [
      Positioned(
        top: 35,
        left: 20,
        // elevationを付けるためMaterialウィジェットを使用
        child: Material(
          elevation: 4,
          child: Container(
            height: 180,
            width: MediaQuery.of(context).size.width * 0.9,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(0.0),
            ),
          ),
        ),
      ),
      // 画像部分
      Positioned(
        top: 0,
        left: 30,
        child: Card(
          elevation: 4,
          shadowColor: Colors.grey.withOpacity(0.5),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15),
          ),
          child: Container(
            height: 200,
            width: 150,
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(10),
                image: const DecorationImage(
                  image: NetworkImage(
                    'https://source.unsplash.com/300x200/?beach',
                  ),
                  fit: BoxFit.fill,
                )),
          ),
        ),
      ),
      const Positioned(
        top: 45,
        left: 200,
        child: SizedBox(
          height: 150,
          width: 180,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // タイトル
              Text(
                'タイトル',
                style: TextStyle(
                  fontWeight: FontWeight.w600,
                  fontSize: 22,
                ),
              ),
              Divider(color: Colors.black),
              // 説明文
              Text(
                'ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。',
                style: TextStyle(
                  color: Colors.grey,
                  fontSize: 16,
                ),
              ),
            ],
          ),
        ),
      ),
    ],
  ),
),

デザイン④

card_4.dart
Card(
  margin: const EdgeInsets.symmetric(horizontal: 20),
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(8),
  ),
  clipBehavior: Clip.antiAliasWithSaveLayer,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      Image.network(
        'https://source.unsplash.com/300x200/?resort',
        height: 160,
        width: double.infinity,
        fit: BoxFit.cover,
      ),
      Container(
        padding: const EdgeInsets.fromLTRB(15, 15, 15, 0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              'タイトル',
              style: TextStyle(
                fontSize: 24,
                color: Colors.grey[800],
              ),
            ),
            const SizedBox(height: 10),
            Text(
              'ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。',
              style: TextStyle(
                fontSize: 15,
                color: Colors.grey[700],
              ),
            ),
            Row(
              children: <Widget>[
                const Spacer(),
                TextButton(
                  style: TextButton.styleFrom(
                    foregroundColor: Colors.transparent,
                  ),
                  child: const Text(
                    'シェア',
                    style: TextStyle(color: Colors.pinkAccent),
                  ),
                  onPressed: () {},
                ),
                TextButton(
                  style: TextButton.styleFrom(
                    foregroundColor: Colors.transparent,
                  ),
                  child: const Text(
                    'もっと見る',
                    style: TextStyle(color: Colors.pinkAccent),
                  ),
                  onPressed: () {},
                ),
              ],
            ),
          ],
        ),
      ),
      const SizedBox(height: 4),
    ],
  ),
),

縦長カードデザイン

デザイン①

card_1.dart
ConstrainedBox(
  constraints: BoxConstraints(
    maxWidth:
        MediaQuery.of(context).size.width * 0.4, // カードの横幅(最大値)
  ),
  child: Card(
    elevation: 4,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(0),
    ),
    child: Column(
      children: [
        // 画像
        SizedBox(
          width: double.infinity,
          height: 128,
          child: Image.network(
            'https://source.unsplash.com/300x200/?bag',
            fit: BoxFit.cover,
          ),
        ),
        // タイトル
        Container(
          width: double.infinity,
          padding: const EdgeInsets.only(left: 4),
          child: Text(
            'タイトル',
            overflow: TextOverflow.ellipsis,
            style: Theme.of(context).textTheme.bodySmall,
          ),
        ),
        // 値段
        Container(
          width: double.infinity,
          padding: const EdgeInsets.only(left: 4),
          child: const Text(
            '1000円',
            style: TextStyle(
              fontSize: 16,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        // アイコンといいね数
        const Visibility(
          visible: true, // いいねが無い場合はfalseを設定する
          child: Row(
            children: [
              Padding(
                padding: EdgeInsets.symmetric(horizontal: 4),
                child: Icon(
                  Icons.favorite,
                  color: Colors.black45,
                  size: 16,
                ),
              ),
              Text(
                '3',
                style: TextStyle(color: Colors.black45),
              ),
            ],
          ),
        ),
      ],
    ),
  ),
),

デザイン②

card_2.dart
Container(
  width: MediaQuery.of(context).size.width * 0.4,
  margin: const EdgeInsets.all(12),
  padding: const EdgeInsets.only(top: 30, bottom: 30),
  decoration: BoxDecoration(
    color: Colors.grey.shade100,
    borderRadius: BorderRadius.circular(20),
    boxShadow: const [
      BoxShadow(
        blurRadius: 10,
        offset: Offset(-10, -10),
        color: Colors.white24,
      ),
      BoxShadow(
        blurRadius: 10,
        offset: Offset(10, 10),
        color: Colors.grey,
      ),
    ],
  ),
  child: Padding(
    padding: const EdgeInsets.symmetric(horizontal: 8),
    child: Column(
      children: [
        // アイコン
        const Icon(
          Icons.rocket_launch,
          color: Colors.black45,
          size: 48,
        ),
        const SizedBox(height: 8),
        // タイトル
        Text(
          'タイトル',
          style: Theme.of(context).textTheme.titleLarge,
        ),
        const SizedBox(height: 8),
        // 説明文
        Text(
          'ここに説明文が入ります。ここに説明文が入ります。ここに説明文が入ります。',
          style: TextStyle(
            fontSize: 15,
            color: Colors.grey[700],
          ),
        ),
      ],
    ),
  ),
),

(最後にソッといいねボタンやバッジを贈るボタンを押して頂けたら幸いですm(_ _)m)

Discussion