Flutterには、Material Designに対応したUIコンポーネントが標準で用意されています。
これまでMaterial DesignのウィジェットはFlutter SDKに含まれており、package:flutter/material.dartから利用する形でした。
現在はMaterial DesignライブラリがFlutter本体から分離され、Flutter公式パッケージのmaterial_uiとして提供されています。
material_uiでは、これまで利用されてきたMaterialAppやScaffold、AppBar、ElevatedButton、TextFieldなどのMaterialウィジェットを利用できます。
また、Material 3のデザインシステム、テーマ、カラー、タイポグラフィ、アニメーションなども提供されています。
material_uiとは
material_uiは、GoogleのMaterial DesignをFlutterで実装する公式ライブラリです。
Flutterチームによって開発されているファーストパーティパッケージで、従来Flutter SDKに含まれていたMaterialライブラリを独立したパッケージとして提供しています。
現在の最新バージョンは1.6.0です。
対応プラットフォームは以下の通りです。
- Android
- iOS
- Linux
- macOS
- Web
- Windows
主な特徴
| 機能 | 内容 |
|---|---|
| Material 3 | GoogleのMaterial Design 3に対応 |
| アプリ構造 | MaterialApp、Scaffold、AppBarなど |
| ナビゲーション | NavigationBar、NavigationDrawer、NavigationRailなど |
| ボタン | ElevatedButton、TextButton、OutlinedButtonなど |
| 入力 | TextField、Checkbox、Radio、Switchなど |
| 選択UI | DropdownMenu、SegmentedButton、Sliderなど |
| ダイアログ | Dialog、AlertDialogなど |
| 表示UI | Card、Chip、ListTile、Badgeなど |
| テーマ | ThemeData、ColorScheme、TextThemeなど |
| カラー | Material 3のColorSchemeやDynamic Color |
| ローカライズ | MaterialLocalizationsなど |
| アニメーション | Material Designのモーションやイージング |
インストール
material_uiはFlutterプロジェクトに追加して利用できます。
Bash
flutter pub add material_ui
またはpubspec.yamlに直接追加します。
YAML
dependencies:
material_ui: ^1.6.0
インポート
従来のMaterialライブラリでは以下のようにインポートしていました。
Dart
import 'package:flutter/material.dart';
material_uiでは、以下のように変更します。
Dart
import 'package:material_ui/material_ui.dart';
基本的なMaterialウィジェットのクラス名は、これまで利用してきたものと同じです。
基本的なアプリを作る
material_uiを利用して、基本的なFlutterアプリを作成できます。
Dart
import 'package:flutter/widgets.dart';
import 'package:material_ui/material_ui.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Material UI'),
),
body: const Center(
child: Text('Hello Material UI'),
),
),
);
}
}
MaterialAppやScaffold、AppBarなど、従来のMaterialライブラリで使用していたウィジェットをそのまま利用できます。
MaterialApp
MaterialAppはMaterial Designアプリケーションのルートとなるウィジェットです。
テーマ、ローカライズ、ナビゲーションなど、Materialアプリに必要な設定をまとめて管理できます。
Dart
MaterialApp(
title: 'My App',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
),
useMaterial3: true,
),
home: const HomePage(),
);
Scaffold
Scaffoldは、Material Designの基本的な画面構造を構築するためのウィジェットです。
Dart
Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: const Center(
child: Text('Hello'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: const Icon(Icons.add),
),
);
AppBar、本文、Floating Action Buttonなどを組み合わせて、一般的なアプリ画面を構築できます。
Material 3
material_uiはMaterial 3に対応しています。
Material 3では、カラー、タイポグラフィ、コンポーネント、モーションなどのデザインシステムが定義されています。
FlutterではThemeDataやColorSchemeを利用してMaterial 3のテーマを設定できます。
Dart
MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
),
),
home: const HomePage(),
);
ColorScheme
Material 3では、アプリ全体のカラーをColorSchemeで管理できます。
例えば、シードカラーからColorSchemeを生成できます。
Dart
final colorScheme = ColorScheme.fromSeed(
seedColor: Colors.blue,
);
これをThemeDataに設定します。
Dart
ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
),
useMaterial3: true,
);
各Materialウィジェットは、このテーマから必要なカラーを取得できます。
ダークモード
ThemeDataを利用することで、ライトテーマとダークテーマを設定できます。
Dart
MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.light,
),
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
),
home: const HomePage(),
);
themeModeを設定することで、使用するテーマを切り替えられます。
Dart
MaterialApp(
theme: lightTheme,
darkTheme: darkTheme,
themeMode: ThemeMode.system,
home: const HomePage(),
);
ボタン
Material Designで使用されるさまざまなボタンが用意されています。
代表的なものとして以下があります。
ElevatedButtonFilledButtonOutlinedButtonTextButtonIconButtonFloatingActionButtonSegmentedButton
例えばElevatedButtonは以下のように使用できます。
Dart
ElevatedButton(
onPressed: () {
print('Pressed');
},
child: const Text('Button'),
);
入力コンポーネント
フォームなどで利用できる入力コンポーネントも提供されています。
代表的なものには以下があります。
TextFieldTextFormFieldCheckboxRadioSwitchSliderRangeSliderDropdownMenu
例えばTextFieldは以下のように利用できます。
Dart
TextField(
decoration: const InputDecoration(
labelText: 'Name',
hintText: 'Enter your name',
),
);
ナビゲーション
Material Designのナビゲーション用コンポーネントも用意されています。
代表的なものは以下です。
NavigationBarNavigationDrawerNavigationRailTabBarBottomSheet
例えば、NavigationBarを利用できます。
Dart
NavigationBar(
selectedIndex: 0,
destinations: const [
NavigationDestination(
icon: Icon(Icons.home),
label: 'Home',
),
NavigationDestination(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
);
ダイアログ
DialogやAlertDialogを利用してダイアログを表示できます。
Dart
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Confirm'),
content: const Text(
'Do you want to continue?',
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancel'),
),
FilledButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('OK'),
),
],
);
},
);
カードやリスト
コンテンツを整理して表示するためのコンポーネントも用意されています。
代表的なものは以下です。
CardListTileChipBadgeDividerCarouselView
例えばCardとListTileを組み合わせることができます。
Dart
Card(
child: ListTile(
leading: const Icon(Icons.person),
title: const Text('User'),
subtitle: const Text('user@example.com'),
),
);
DatePicker
Material DesignのDatePickerも利用できます。
Dart
final date = await showDatePicker(
context: context,
firstDate: DateTime(2020),
lastDate: DateTime(2030),
initialDate: DateTime.now(),
);
ユーザーが日付を選択した結果をDateTime?として取得できます。
SearchBar
検索UIとしてSearchBarやSearchAnchorも用意されています。
Dart
SearchBar(
hintText: 'Search',
onChanged: (value) {
// 検索処理
},
);
Material Designに沿った検索UIを比較的少ないコードで構築できます。
MaterialLocalizations
material_uiにはMaterial UIのローカライズ機能も含まれています。
例えば、アプリのローカライズ設定ではGlobalMaterialLocalizations.delegatesを利用できます。
Dart
MaterialApp(
localizationsDelegates:
GlobalMaterialLocalizations.delegates,
supportedLocales: const [
Locale('en'),
Locale('ja'),
],
home: const HomePage(),
);
GlobalMaterialLocalizations.delegatesは、Material、Cupertino、Flutter Widgetsに必要なローカライズデリゲートをまとめて提供できます。
既存のFlutterアプリから移行する
material_uiの重要なポイントは、既存のFlutterアプリで利用していたMaterialライブラリを独立パッケージへ移行できることです。
これまで、
Dart
import 'package:flutter/material.dart';
としていたコードを、
Dart
import 'package:material_ui/material_ui.dart';
へ変更します。
Flutterでは、この移行を自動化するためのdart fixも提供されています。
Bash
dart fix --apply --code=migrate_design_widgets
このコマンドによって、Materialウィジェットのインポートを新しいパッケージへ移行できます。
既存パッケージとの互換性
Flutterアプリを移行する際に問題になりやすいのが、まだpackage:flutter/material.dartを使用しているサードパーティパッケージです。
material_uiには、このような既存コードとの互換性を確保するためのMaterialUiCompatibilityBridgeが用意されています。
Dart
import 'package:material_ui/material_ui.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, child) {
return MaterialUiCompatibilityBridge(
child: child!,
);
},
home: const HomeScreen(),
);
}
}
既存のパッケージが従来のMaterialライブラリを利用している場合でも、互換性ブリッジを利用することで段階的に移行できます。
なぜMaterialライブラリが分離されたのか
これまでMaterialライブラリはFlutter Frameworkの一部でした。
そのため、Materialの変更や改善を行う場合、Flutter SDKのリリースサイクルと結びついていました。
material_uiとして分離することで、MaterialライブラリをFlutter Framework本体とは独立して開発・リリースできるようになります。
これにより、Material UIの修正や新機能をFlutter SDK全体のアップデートとは別に提供できるようになります。
Flutter公式では、この分離によってMaterialライブラリの開発をより速く行えることや、Flutter Framework本体をよりスタイルに依存しない構成へ進められることが説明されています。
flutter/material.dartはどうなる?
現在のFlutterでは、従来のpackage:flutter/material.dartからmaterial_uiへの移行が進められています。
Flutter Framework側のmaterial.dartには、現在material_ui/material_ui.dartを使用するよう促す非推奨指定が入っています。
そのため、新しくMaterial Designを利用するコードでは、material_uiを利用する形が推奨されます。
まとめ
material_uiは、FlutterのMaterial Designライブラリを独立したパッケージとして提供するFlutter公式パッケージです。
従来のFlutter SDKに含まれていたMaterialライブラリをベースとして、以下のような機能を利用できます。
MaterialAppScaffoldAppBarNavigationBarNavigationDrawerElevatedButtonFilledButtonOutlinedButtonTextFieldCheckboxSwitchSliderDropdownMenuDialogCardListTileThemeDataColorSchemeTextTheme- Material 3
- Material Localizations
特に既存のFlutterアプリでは、package:flutter/material.dartからpackage:material_ui/material_ui.dartへ移行することが主な用途になります。
Flutter本体からMaterialライブラリを切り離すことで、今後はFlutter SDK全体のリリースとは独立してMaterial UIの改善や更新を受けられるようになる点も大きな特徴です。
