Open5
Flutterのlayoutを理解したい
![JboyHashimoto](https://res.cloudinary.com/zenn/image/fetch/s--CHq5qY5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/3c90bcc43f.jpeg)
アプリのlayoutわかっていない。
どんなものを参考にすればいいのか?
monoさんの昔のブログに、参考になりそうな情報が載っていた!
🧑🎓昔のサイトだけど参考になった!
layoutについては、昔から変わることがないので、こちらが参考になった!
AppBarに自分の配置したいパーツを置きたい。
やったこと
- leadingはデフォルトだと、幅が狭いので、leadingWidth: 200を指定して、横幅を広げた
- 2行、3列のメニューを作るには、Columnの中に、Rowを2個配置する
- mainAxisAlignment: MainAxisAlignment.spaceEvenlyを使ってメニューのテキストの幅を均一にした
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leadingWidth: 200, // leadingの幅を指定
leading: Container(
// AppBarの左側にWidgetを配置する
color: Colors.yellow,
width: 200,
height: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 余白を均等に配置
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
),
actions: [
Container(
color: Colors.green,
width: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
)
],
toolbarHeight: 100,
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
);
}
}
🔧ビルドした状態
均一に並べることができた。
![JboyHashimoto](https://res.cloudinary.com/zenn/image/fetch/s--CHq5qY5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/3c90bcc43f.jpeg)
画面左にサイドバーのようなものを作りたい場合はどうする?
NavitationRailというウイジェットを使うらしいが、これでは実現できそうになかった😅
Columnを使って、サイドバーのような見た目に見えるようにしてみた。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leadingWidth: 200, // leadingの幅を指定
leading: Container(
// AppBarの左側にWidgetを配置する
color: Colors.yellow,
width: 200,
height: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 余白を均等に配置
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
),
actions: [
Container(
color: Colors.green,
width: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
)
],
toolbarHeight: 100,
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Container(
width: 50,
color: Colors.pinkAccent,
child: Column (
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20),
Icon(Icons.star_outline, size: 30),
// 横幅20のDividerを表示
const SizedBox(
width: 50,
child: Divider(color: Colors.grey),
),
SizedBox(height: 20),
Icon(Icons.home, size: 30),
SizedBox(height: 20),
Icon(Icons.comment, size: 30),
SizedBox(height: 20),
Icon(Icons.add, size: 30),
SizedBox(height: 20),
Icon(Icons.settings, size: 30),
],
),
),
);
}
}
何とか、それっぽく見せてみた💦
![JboyHashimoto](https://res.cloudinary.com/zenn/image/fetch/s--CHq5qY5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/3c90bcc43f.jpeg)
ダッシュボードぽい画面を作りたい
画面に左に、サイドバーぽく見せたウイジェットを配置して、右側の中央に、テキストと入力フォームを並べるのをやってみた。それっぽい見た目にはなったが、サイドバーはこれでいいか疑問?
レイアウトは、綺麗にはできた。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final inputValues = [
(title: '会社名', controller: TextEditingController()),
(title: '事業者番号', controller: TextEditingController()),
(title: '事業者名', controller: TextEditingController()),
(title: '事業者名カナ', controller: TextEditingController()),
(title: '郵便番号', controller: TextEditingController()),
(title: '都道府県', controller: TextEditingController()),
(title: '市町村', controller: TextEditingController()),
(title: '番地', controller: TextEditingController()),
(title: '建物名', controller: TextEditingController()),
(title: '会社電話', controller: TextEditingController()),
(title: '会社FAX', controller: TextEditingController()),
(title: '会社メールアドレス', controller: TextEditingController()),
];
/// titleからcontrollerに入力されたテキスト情報を取得する
String controllerFromTitle(String title) => inputValues
.firstWhere((element) => element.title == title)
.controller
.text;
void dispose() {
for (final value in inputValues) {
value.controller.dispose();
}
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leadingWidth: 200, // leadingの幅を指定
leading: Container(
// AppBarの左側にWidgetを配置する
color: Colors.yellow,
width: 200,
height: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 余白を均等に配置
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
),
actions: [
Container(
color: Colors.green,
width: 200,
child: Column(
children: [
const SizedBox(height: 20),
Container(
color: Colors.red,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
const SizedBox(height: 20),
Container(
color: Colors.blue,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Top'),
const SizedBox(width: 10),
const Text('menu'),
const SizedBox(width: 10),
const Text('info'),
const SizedBox(width: 10),
],
),
),
],
),
)
],
toolbarHeight: 100,
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(// Widgetが増えた気に、overflowしないようにする
child: Stack(// サイドバーとフォームを重ねる
children: [
Container(
height: MediaQuery.of(context).size.height, // 画面の高さを取得して、画面下の余白をなくす
color: Colors.lightBlueAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 40),
// for文を使って、TextEditingControllerを生成
for (final e in inputValues)
Padding(
padding: const EdgeInsets.only(bottom: 12),// 下の余白を12にする
child: TextFormFieldWithTitle(// コンポーネント化した、TextFormFieldを呼び出す
inputValue: e,// 生成したTextEditingControllerを渡す
),
),
],
),
),
Container(
width: 50,
height: MediaQuery.of(context).size.height, // 画面の高さを取得して、画面下の余白をなくす
color: Colors.pinkAccent,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(height: 20),
Icon(Icons.star_outline, size: 30),
// 横幅20のDividerを表示
const SizedBox(
width: 50,
child: Divider(color: Colors.grey),
),
SizedBox(height: 20),
Icon(Icons.home, size: 30),
SizedBox(height: 20),
Icon(Icons.comment, size: 30),
SizedBox(height: 20),
Icon(Icons.add, size: 30),
SizedBox(height: 20),
Icon(Icons.settings, size: 30),
],
),
),
],
),
),
);
}
}
// 入力フォームをコンポーネント化する
class TextFormFieldWithTitle extends StatelessWidget {
const TextFormFieldWithTitle({
required this.inputValue,
super.key,
});
final ({String title, TextEditingController controller}) inputValue;
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 160,
height: 40,
child: Text(
inputValue.title,
style: const TextStyle(color: Colors.grey),
),
),
SizedBox(
width: 600,
height: 40,
child: TextFormField(
controller: inputValue.controller,
decoration: const InputDecoration(
hintText: '○○○○○○○○○',
fillColor: Colors.white,
filled: true,
),
),
),
],
);
}
}
![JboyHashimoto](https://res.cloudinary.com/zenn/image/fetch/s--CHq5qY5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/3c90bcc43f.jpeg)
パンくずリストのような見た目にする
パンくずリストとは、ホームページを訪れたユーザーが、「現在どこのページにアクセスしているか」を知るための「道しるべ」です。
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
class BaseUI extends StatefulWidget {
const BaseUI({Key? key}) : super(key: key);
State<BaseUI> createState() => _BaseUIState();
}
class _BaseUIState extends State<BaseUI> {
final fontColor = Colors.black;
final List<String> items = [
'Item1',
'Item2',
'Item3',
'Item4',
'Item5',
'Item6',
'Item7',
'Item8',
];
String? selectedValue;
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[50],
appBar: AppBar(
backgroundColor: Colors.white,
// 影を消す
elevation: 0,
leadingWidth: 500,
// 高さ調整
toolbarHeight: 100,
leading: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Row(
children: [
Text('屋号', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('サービス種別', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('事業者番号', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
],
),
const SizedBox(height: 8),
Row(
children: [
Text('ようこそ', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('会社名', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('ログイン番号', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('ログイン名', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
],
),
const SizedBox(height: 8),
Row(
children: [
Text('台帳管理', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('アセスメント', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('予定・実績管理', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('国保連請求管理', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('各種情報出力', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
],
),
],
),
),
// AppBar右側にメニューを作る
actions: [
Padding(
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
child: Align(
alignment: Alignment.topRight,
child: Row(
children: [
Text('よくあるご質問', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('ログアウト', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('レセプトTOP', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
Text('サイトTOP', style: TextStyle(color: fontColor)),
const SizedBox(width: 8),
],
),
),
)
],
),
body: SingleChildScrollView(
child: Column(
children: [
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.only(left: 40),
width: 300,
height: 100,
child: Column(
children: [
Row(
children: [
Text('TOP >'),
const SizedBox(width: 8),
Text('台帳管理 >'),
const SizedBox(width: 8),
Text('利用者管理画面'),
],
),
const SizedBox(height: 10),
Row(
children: [
Text('利用者管理画面', style: TextStyle(fontSize: 25)),
],
),
],
),
),
Container(
// color: Colors.orange,
width: 440,
height: 120,
child: Column(
children: [
Container(
// color: Colors.cyan,
child: Row(
children: [
Column(
children: [
Container(
// color: Colors.blue,
alignment: Alignment.topLeft,
width: 420,
child: Text('スタッフ選択')),
const SizedBox(height: 10),
Row(
children: [
DropdownButtonHideUnderline(
child: DropdownButton2<String>(
isExpanded: true,
hint: const Row(
children: [
SizedBox(
width: 4,
),
Expanded(
child: Text(
'Select Item',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
items: items
.map((String item) =>
DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
fontWeight:
FontWeight.bold,
color: Colors.black,
),
overflow:
TextOverflow.ellipsis,
),
))
.toList(),
value: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value;
});
},
buttonStyleData: ButtonStyleData(
height: 50,
width: 200,
padding: const EdgeInsets.only(
left: 14, right: 14),
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(14),
border: Border.all(
color: Colors.black26,
),
color: Colors.white,
),
elevation: 2,
),
iconStyleData: const IconStyleData(
icon: Icon(
Icons.keyboard_arrow_down,
),
iconSize: 14,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight: 200,
width: 200,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(14),
color: Colors.white,
),
offset: const Offset(-20, 0),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness:
MaterialStateProperty.all(6),
thumbVisibility:
MaterialStateProperty.all(true),
),
),
menuItemStyleData:
const MenuItemStyleData(
height: 40,
padding: EdgeInsets.only(
left: 14, right: 14),
),
),
),
const SizedBox(width: 40),
SizedBox(
width: 140,
height: 30,
child: ElevatedButton(
onPressed: () {},
child: const Text('検索')),
),
SizedBox(width: 40),
],
),
],
),
],
),
),
],
),
),
],
),
],
),
),
);
}
}
パッケージもあるらしい?
![JboyHashimoto](https://res.cloudinary.com/zenn/image/fetch/s--CHq5qY5F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_70/https://storage.googleapis.com/zenn-user-upload/avatar/3c90bcc43f.jpeg)
Webページのヘッダーをトレースする
ColumnとRowは、Containerでラップして、mainAxisAlignment: MainAxisAlignment.endにしないと、右端に寄せられなかった。
leadingは、Alignを使わないと、左端に寄せれなかった。
import 'package:flutter/material.dart';
class FreeUI extends StatefulWidget {
const FreeUI({Key? key}) : super(key: key);
State<FreeUI> createState() => _FreeUIState();
}
class _FreeUIState extends State<FreeUI> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
leadingWidth: 800,
toolbarHeight: 100,
elevation: 0, // 影を非表示
leading: SizedBox(
width: 200,
height: 50,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: 200,
height: 50,
child: Image.network(
'data:image/png;base64,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'),
),
),
Align(
alignment: Alignment.centerLeft,
child: Container(
child: MenuBar(children: [
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.home)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.person)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.auto_graph_sharp)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.credit_card)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.money)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.business)),
SubmenuButton(menuChildren: [
MenuItemButton(child: Text('Chick'), onPressed: () {}),
], child: Icon(Icons.settings)),
]),
),
),
],
),
),
actions: [
Container(
width: 550,
child: Padding(
padding: const EdgeInsets.only(right: 20),
child: Column(
children: [
SizedBox(height: 10),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: [
Icon(Icons.play_arrow_rounded, color: Colors.black),
Text('連携アプリを探す',
style:
TextStyle(color: Colors.black, fontSize: 12)),
SizedBox(width: 5),
],
),
Row(
children: [
Icon(Icons.apps, color: Colors.black),
Text('プロダクト切替',
style:
TextStyle(color: Colors.black, fontSize: 12)),
],
),
SizedBox(width: 5),
Row(
children: [
Icon(Icons.person, color: Colors.black),
Text('アカウント',
style:
TextStyle(color: Colors.black, fontSize: 12)),
],
),
],
),
),
SizedBox(height: 10),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text('レポート終了完了',
style: TextStyle(color: Colors.black, fontSize: 12)),
SizedBox(width: 5),
Text('コメント0件',
style: TextStyle(color: Colors.black, fontSize: 12)),
SizedBox(width: 5),
Text('スタータープラン',
style: TextStyle(color: Colors.black, fontSize: 12)),
SizedBox(width: 5),
Text('2023~01-01~2023-12-31',
style: TextStyle(color: Colors.black, fontSize: 12)),
SizedBox(width: 5),
Text('事業所名(未設定)',
style: TextStyle(color: Colors.black, fontSize: 12)),
],
),
)
],
),
),
)
],
));
}
}