NorthNest
モバイル開発

Flutterで実装するLiquid Glass UI:iOS 26ライクなガラス表現を簡単に再現

📅 2025年9月18日
✍️ 王 家豪
#Flutter
#FlutterFlow
#UIデザイン
#LiquidGlass
#Glassmorphism
#iOS

Flutterで実装するLiquid Glass UI

みなさん、こんにちは!
本記事では、Flutterで Liquid Glass(ガラス調UI) を簡単に実装する方法を紹介します。

iOS 26でも採用されている、
ガラスのように透けて見えるモダンなUI をFlutterで再現してみましょう。

FlutterFlowでもそのまま使える
カスタムWidget実装 をベースに解説します。


🎨 Liquid Glass(Glassmorphism)とは?

Liquid Glassは、以下の要素を組み合わせたデザイン手法です。

  • 背景のブラー(ぼかし)効果
  • 半透明カラー
  • 光を意識したグラデーション
  • 角丸(ラウンド)シェイプ

背景と完全に分離せず、
奥行き・透明感・高級感 を演出できるため、

  • iOSアプリ
  • 音楽・天気・金融系UI
  • ダッシュボード

などで特に相性が良いデザインです。


🧠 FlutterでLiquid Glassを実現する考え方

Flutterでは以下のWidgetを組み合わせます。

| Widget | 役割 |
|------|------|
| BackdropFilter | 背景をぼかす |
| ClipRRect | ブラー範囲を制限 |
| Container | 半透明・グラデーション |
| Border | ガラスの縁表現 |

👉 BackdropFilter単体では不十分
👉 必ずClipRRectとセットで使う のがポイントです。


🛠 実装方法(FlutterFlow対応)

以下は FlutterFlowのカスタムWidget として使える実装例です。
通常のFlutterプロジェクトでもそのまま利用できます。


コード全体(Glassmorphism Custom Widget)

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

class GlassmorphismCustomWidget extends StatefulWidget {
  const GlassmorphismCustomWidget({
    super.key,
    this.width,
    this.height,
    required this.text,
    required this.isScroll,
    required this.fontSize,
    required this.fontWeight,
    required this.textAlign,
  });

  final double? width;
  final double? height;
  final String text;
  final bool isScroll;
  final double fontSize;
  final String fontWeight;
  final String textAlign;

  @override
  State<GlassmorphismCustomWidget> createState() =>
      _GlassmorphismCustomWidgetState();
}

class _GlassmorphismCustomWidgetState extends State<GlassmorphismCustomWidget> {
  FontWeight _getFontWeight(String? weight) {
    switch (weight?.toLowerCase()) {
      case 'bold':
        return FontWeight.w700;
      case 'medium':
        return FontWeight.w500;
      case 'light':
        return FontWeight.w300;
      default:
        return FontWeight.w500;
    }
  }

  TextAlign _getTextAlign(String? align) {
    switch (align?.toLowerCase()) {
      case 'left':
        return TextAlign.left;
      case 'right':
        return TextAlign.right;
      case 'center':
      default:
        return TextAlign.center;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.center,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(12),
        child: BackdropFilter(
          filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
          child: Container(
            padding: const EdgeInsets.all(6),
            width: widget.width ?? MediaQuery.sizeOf(context).width * 0.4,
            height: widget.height ?? MediaQuery.sizeOf(context).height * 0.05,
            decoration: BoxDecoration(
              gradient: LinearGradient(
                colors: [
                  Colors.white.withOpacity(0.2),
                  Colors.blueAccent.withOpacity(0.3),
                ],
                begin: Alignment.topLeft,
                end: Alignment.bottomRight,
              ),
              borderRadius: BorderRadius.circular(12),
              border: Border.all(
                color: Colors.white.withOpacity(0.2),
                width: 1,
              ),
            ),
            alignment: Alignment.center,
            child: widget.isScroll
                ? SingleChildScrollView(
                    child: Text(
                      widget.text,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: widget.fontSize,
                        fontWeight: _getFontWeight(widget.fontWeight),
                      ),
                      textAlign: _getTextAlign(widget.textAlign),
                    ),
                  )
                : Text(
                    widget.text,
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: widget.fontSize,
                      fontWeight: _getFontWeight(widget.fontWeight),
                    ),
                    textAlign: _getTextAlign(widget.textAlign),
                  ),
          ),
        ),
      ),
    );
  }
}

📱 表示イメージ 表示イメージ

ガラス調カードUI

•	背景が自然に透ける
•	境界が柔らかく、浮いて見える
•	iOS 26ライクな質感

⚠️ パフォーマンス注意点

•	BackdropFilterは 描画コストが高め  
•	リスト内で多用しない  
•	静的UI・カード・ヘッダー向き

対策例:

•	スクロール領域外に配置  
•	RepaintBoundaryの利用  
•	ブラー値(sigma)を下げる

🎛 カスタマイズ例

•	ダークモード用に透明度を下げる  
•	グラデーションを単色に変更  
•	影(BoxShadow)を追加して浮遊感UP  
•	背景色に応じて色を切り替え

✅ まとめ

•	Flutterでは BackdropFilter + ClipRRect でLiquid Glassを再現可能  
•	FlutterFlowでも カスタムWidgetとして簡単導入  
•	半透明 × ブラー × グラデーションで iOS 26風UIが完成  

デザインに少し加えるだけで、 アプリ全体の 高級感・没入感 が大きく向上します。

ぜひ自分のアプリに取り入れてみてください ✨


AI活用についてご相談ください

貴社のビジネス課題に最適なAIソリューションをご提案いたします