【Flutter】デバイスごとのUI調整!SafeArea活用法

対象者

  • Flutterを使用したアプリ開発に携わるITエンジニアやアプリ開発者
  • SafeAreaに関する知識や技術を習得し、デバイス対応のアプリ開発をスムーズに行いたい人
  • Flutterでノッチやステータスバーをどのように対応すれば良いのか分からない人

はじめに

スマートフォンのデザインが多様化し、ノッチや丸みを帯びた画面端が増える中、アプリのレイアウト調整が難しく感じられることがありますよね。Flutterでアプリ開発を行う際、特にUIの調整が重要となります。そんな悩みを解決するために、今回はFlutterのSafeAreaウィジェットを活用して、どのデバイスでも美しいレイアウトを実現する方法を解説します。

この記事では、SafeAreaの基本的な使い方から、特定の画面端のみ無効化する方法、さらにSafeAreaをカスタマイズする方法まで取り上げます。実際にSafeAreaを用いたサンプルコードを紹介し、理解を深めていただくことができます。
また、SafeAreaの有無を使い分ける方法も紹介してますので、美しいUIの実装の足がかりになります。

記事を読んでいただくことで、あなたがFlutter SafeAreaを使いこなせるようになります。

Flutter SafeAreaの基本

SafeAreaの概要

SafeAreaは、ノッチやホームバーでWidgetが隠れないように、適切に空白を開けてくれる便利なWidgetです。近年のデバイスの画面形状が多様化し、単純な長方形以外の形状が増えているため、アプリの一部がデバイスに隠れてしまうことがあります。アプリ開発者がここのデバイスに対して、適切なWidgetの配置を設定していくのは不可能です。
SafeAreaは、そのような問題を解決してくれます。

基本的な使い方

SafeAreaの基本的な使い方は簡単で、WidgetをSafeAreaで囲むだけです。例えば、ListViewをSafeAreaで囲んだ場合、ノッチやホームバーにWidgetが隠れることがなくなります。

SafeArea なし あり
画面 Mateerial2 Mateerial3
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: ListView.builder(itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('Item $index'),
          );
        }),
      ),
    );
  }

SafeAreaのカスタマイズ方法

SafeAreaでは、特定の画面端だけ無効化することができます。SafeAreaウィジェットには、left、top、right、bottomという4つのプロパティがあり、それぞれの画面端を無効化するかどうかを指定できます[5]。デフォルトでは、これらのプロパティはすべてtrueに設定されており、各画面端で空白が確保されます。これらのプロパティをfalseに設定することで、特定の画面端だけSafeAreaの効果を無効化できます。

例えば、下部の空白だけを無効化したい場合、以下のようにSafeAreaウィジェットを使用します。

SafeArea(
    bottom: false, // 下部のSafeAreaを無効化
    child: ListView.builder(itemBuilder: (BuildContext context, int index) {
      return ListTile(
        title: Text('Item $index'),
      );
    }),
)

SafeAreaが有効になる部分と無効になる部分を分ける方法

常にSafeAreaにWidgetを置きたいとは限りません。
例えば、背景画像は画面いっぱいにして、文字などの情報はSafeArea内に収めたい場合があります。そのときは、Stackを使って、背景画像にはSafeAreaを使わず、文字情報はSafeAreaを使うようにします。

Widget build(BuildContext context) {
return Scaffold(
  body: Stack(
    children: [
      Container(color: Colors.blue), // 青背景が画面全体に表示される
      SafeArea(
        child: ListView.builder(
            itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('Item $index'),
          );
        }),
      ),
    ],
  ),
);
}

具体的に背景画像を全画面に出す方法は以下に記載してますので、ご覧下さい。

【Flutter】画面一杯に背景画像を表示する

F&Q

Q1: SafeAreaウィジェットはどのような目的で使用されますか?

A1: SafeAreaウィジェットは、ノッチやホームバーなどのデバイス固有の要素で隠れてしまう部分を適切に空けるために使用されます。これにより、デバイスごとの適切なレイアウト調整が可能となり、アプリの見た目を向上させることができます。

Q2: SafeAreaの効果を特定の画面端だけ無効化する方法はありますか?

A2: はい、SafeAreaを使って特定の画面端だけ効果を無効化することができます。具体的には、SafeAreaウィジェットのプロパティ(top、bottom、left、right)をfalseに設定することで、その画面端に対するSafeAreaの効果を無効化できます。

Q3: SafeAreaを使用することで得られるメリットは何ですか?

A3: SafeAreaを使用することで、以下のメリットが得られます。

  • ノッチやホームバーで隠れる部分を適切に空けることができる
  • デバイスごとの適切なレイアウト調整が可能になる
  • 特定の画面端だけSafeAreaの効果を無効化することができ、柔軟なデザインが実現可能となる

これらのメリットにより、ユーザーに快適なアプリ体験を提供できます。

まとめ

SafeAreaウィジェットは、ノッチやホームバーで隠れてしまう部分を適切に空ける役割を果たします。SafeAreaを使うことで、デバイスごとの適切なレイアウト調整が可能となり、アプリの見た目を向上させることができることを勉強しました。また、特定の画面端だけSafeAreaの効果を無効化する方法を学びました。

全ソース

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        bottom: false, // 下部のSafeAreaを無効化
        child: ListView.builder(itemBuilder: (BuildContext context, int index) {
          return ListTile(
            title: Text('Item $index'),
          );
        }),
      ),
    );
  }
}