こんにちは。広瀬マサルです。
マルチプラットフォームかつ単一コードでアプリ開発が可能な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を構築していきます。
@override
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
スポンサーを随時募集してます。ご支援お待ちしております!