【Flutter】画面サイズや向きに対して最適なレイアウトを構築できるUIパッケージを作った
こんにちは。広瀬マサルです。
マルチプラットフォームかつ単一コードでアプリ開発が可能なFlutterの特徴を活かし、単一コードで複数のプラットフォームの見た目を調整できるパッケージを作りました。
使い方をまとめたので興味ある方はぜひ使ってみてください!
masamune_universal_ui
はじめに
Flutterは様々なプラットフォームに対応できる利点がある一方で、プラットフォームごとのUIの違いによって開発者が悩まされる欠点があります
Webやデスクトップ向けに開発する場合、タブレット向けのUIも考慮しなければならないため開発コストが上がってしまいます。
Flutterのウィジェットはプラットフォームに依存しないため、そのままではプラットフォーム固有のUIを実現できません。そのため、開発者はプラットフォームごとにUIをカスタマイズする必要があります。
Masamune Universal UIはレスポンシブデザインに対応し、ワンコードで様々なプラットフォーム上に対応可能なUIを生成するウィジェットを集めたフレームワークパッケージです。
Web、iOS、Android、デスクトップ向けに1つのコードで開発することができ、画面サイズに応じて表示が変化するため、開発者はそれぞれのプラットフォーム向けにUIをカスタマイズする必要がありません。
このパッケージを使用することで、プラットフォーム間でのUIの差を気にすることなく開発を進めることができます。
このパッケージはCSSのレイアウトフレームワークで有名なbootstrapをベースにしています。
横12個のグリッドレイアウトを指定でき、画面の横幅に応じて横並びから縦並びへと自然に画面レイアウトを再構築します。
インストール
下記パッケージをインポートします。
Masamuneフレームワークを利用している前提となるためMasamuneのパッケージも合わせてインポートしてください。
flutter pub add masamune_universal_ui
flutter pub add masamune
実装
事前準備
Masamuneフレームワークを利用している前提となります。
MasamuneApp
やrunMasamuneApp
のmasamuneAdapters
にUniversalMasamuneAdapter
を渡して初期化してください。
void main() {
runMasamuneApp(
(adapters) => MasamuneApp(
title: title,
appRef: appRef,
theme: theme,
routerConfig: router,
localize: l,
authAdapter: authAdapter,
modelAdapter: runtimeModelAdapter,
storageAdapter: storageAdapter,
functionsAdapter: functionsAdapter,
masamuneAdapters: adapters,
),
masamuneAdapters: [
const UniversalMasamuneAdapter(),
],
);
}
基本UI
基本的にはFlutterのUIを作る方法と変わりません。ScaffoldやAppBarなどの代わりにUniversalScaffold
やUniversalAppBar
などのウィジェットを指定してUIを構築していきます。
Widget build(BuildContext context, PageRef ref) {
return UniversalScaffold(
appBar: UniversalAppBar(title: Text("Title"), backgroundColor: theme.color.secondary),
body: UniversalColumn(
crossAxisAlignment: CrossAxisAlignment.start,
children:[
Center(child: CircleAvatar(backgroundImage: theme.asset.userIcon.provider)),
Text("User Name", style: theme.text.displayMedium)
]
)
);
}
UniversalScaffold
Scaffoldの代わりになるウィジェットです。通常のScaffoldに加えて下記の機能を利用可能です。
-
Header
- bodyの上部にウィジェットを配置可能です。
-
Footer
- bodyの下部にウィジェットを配置可能です。
-
Sidebar
- bodyの左側にウィジェットを配置可能です。モバイル向けのUIの場合は
body
とfooter
の間に表示されます。
- bodyの左側にウィジェットを配置可能です。モバイル向けのUIの場合は
-
LoadingFutures
、LoadingWidget
- loadingFuturesに
Future
(もしくはFutureOr
)を与えるとFutureが終了するまでbody等を表示せずにインジケーターを表示します。 - loadingWidgetを指定するとインジケーターを指定したものに変更可能です。
- loadingFuturesに
-
width
、height
、borderRadius
- Scaffoldの画面全体をサイジングできます。
-
TransitionQuery.centerModal
などでページ遷移したときにモーダルのように利用することが可能です。
UniversalAppBar
AppBarの代わりになるウィジェットです。
title
やaction
の位置がPC向けとモバイル向けの場合で調整されます。
また通常のAppBarに加えて下記の機能を利用可能です。
-
subtitle
- titleの下に小さく表示するサブタイトルです。
UniversalSliverAppBar
AppBarの代わりになるウィジェットです。UniversalScaffold
やUniversalUI
ウィジェットを合わせて使うことで意識することなくSliver系のAppBarを利用できるようになります。
フィーチャー画像等をヘッダ部分に追加したい場合はこちらを利用してください。
そのままUniversalAppBar
を入れ替えるだけで利用可能です。
UniversalContainer
UniversalScaffold
のbody
直下に置くことで効果を発揮するContainer
ウィジェットです。
Container
と同じように利用可能ですが、画面サイズに応じて自動でパディングが調整されます。
UniversalColumn
UniversalScaffold
のbody
直下に置くことで効果を発揮するColumn
ウィジェットです。
Column
と同じように利用可能ですが、画面サイズに応じて自動でパディングが調整されます。
またchildren
にResponsive
のウィジェットを直下に置くことでグリッドデザインを作成することが可能です。(詳しくは下記をご参照ください)
UniversalListView
UniversalScaffold
のbody
直下に置くことで効果を発揮するListView
ウィジェットです。
ListView
と同じように利用可能ですが、画面サイズに応じて自動でパディングが調整されます。
またchildren
にResponsive
のウィジェットを直下に置くことでグリッドデザインを作成することが可能です。(詳しくは下記をご参照ください)
UniversalSliverAppBar
を利用している場合は、内部でCustomScrollViewが利用されるので意識することなくSliver系のリストに変化します。
UniversalSideBar
UniversalScaffold
のsideBar
直下に置くことで効果を発揮するサイドバーウィジェットです。
画面サイズに応じて自動でパディングが調整されます。
グリッドデザイン
基本的な概念はbootstrapのページを参考にしてください。
https://getbootstrap.com/docs/5.3/layout/breakpoints/
このパッケージではUniversalColumn
やUniversalListView
→ Responsive
といった形でウィジェットを組んでいくことによりグリッドデザインを組み立てることができます。
Responsive
にてxs
、sm
、md
、lg
、xl
、xxl
、の各ブレークポイントにて12個中のいくつに分割するかを指定することができます。
UniversalListView(
children: [
Responsive(
lg: 12,
child: Container(
color: Colors.red,
height: 100,
),
),
Responsive(
sm: 6,
child: Container(
color: Colors.green,
height: 100,
),
),
Responsive(
sm: 6,
child: Container(
color: Colors.blue,
height: 100,
),
),
],
);
おわりに
自分で使う用途で作ったものですが実装の思想的に合ってそうならぜひぜひ使ってみてください!
また、こちらにソースを公開しているのでissueやPullRequestをお待ちしてます!
また仕事の依頼等ございましたら、私のTwitterやWebサイトで直接ご連絡をお願いいたします!
GitHub Sponsors
スポンサーを随時募集してます。ご支援お待ちしております!
Discussion