見出し画像

Flutterでのダイアログ利用

こんにちは、株式会社Pentagonでエンジニアをしている阿久津です。

今回はFlutterでダイアログの利用方法について取り上げます。

ダイアログとは

ISOによると、"ユーザとシステムが相互作用するもの"みたいな定義らしい。

interaction between a user and an interactive system as a sequence of user actions (inputs) and system responses (outputs) in order to achieve a goal

例(GitHubをよくわからず操作している時、押したらダメ、絶対)

スクリーンショット 2021-08-30 1.36.00

ポップアップ、モーダルとか色々と言い方(一般的な意味も若干違う)があるものの、今回の記事では以下をダイアログと呼びます。

モーダル = "画面の上になんか出てくるやつ"

Flutterで使えるダイアログ

以下のような"中央に浮き上がってくるタイプ"、"下部からせり上がってくるタイプ"の2種類が簡単に利用できます。

画像2

ダイアログの実装方法

中央に浮き上がってくるタイプ(showDialog)

 void _showDialog(BuildContext context) {
   showDialog(
     context: context,
     builder: (context) {
       return const AlertDialog(
         content: Text('真ん中に出てくるやつ'), // <= ここでダイアログに表示したいWidgetを返してあげればOK
       );
     },
   );
 }

下部からせり上がってくるタイプ(showModalBottomSheet)

 void _showModalBottomSheet(BuildContext context) {
   showModalBottomSheet(
     context: context,
     builder: (context) {
       return const SizedBox( // <= ここでダイアログに表示したいWidgetを返してあげればOK
         height: 150,
         child: Text(
           '下から出て来るやつ',
           textAlign: TextAlign.center,
           style: TextStyle(fontSize: 16), 
         ),
       );
     },
   );
 }

簡単。以上です。

注意点(ハマるかもポイント)

問題1:ダイアログの内部でListViewやColumnを利用すると縦幅が伸びてしまう。

 void _showDialogWithColumn(BuildContext context) {
   showDialog(
     context: context,
     builder: (context) {
       return AlertDialog(
         content: Column( // <= ここでダイアログに表示したいWidgetを返してあげればOK
           children: const [ 
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
           ],
         ),
       );
     },
   );
 }

画像3

解決法1: `mainAxisSize: MainAxisSize.min,`を設定

  void _showDialogWithColumn(BuildContext context) {
   showDialog(
     context: context,
     builder: (context) {
       return AlertDialog(
         content: Column(
           mainAxisSize: MainAxisSize.min, <= ここ
           children: const [
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
           ],
         ),
       );
     },
   );
 }

画像4

問題2:ListViewを使うとレンダリングで怒られる

 void _showDialogWithList(BuildContext context) {
   showDialog(
     context: context,
     builder: (context) {
       return AlertDialog(
         content: ListView(
           children: const [
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
             Text('真ん中に出てくるやつ'),
           ],
         ),
       );
     },
   );
 }
======== Exception caught by rendering library =====================================================
The following assertion was thrown during paint():
RenderBox was not laid out: RenderPhysicalShape#94df0 relayoutBoundary=up2
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'

解決法2:SizedBoxでListViewのサイズを指定する

 void _showDialogWithList(BuildContext context) {
   showDialog(
     context: context,
     builder: (context) {
       return AlertDialog(
         content: SizedBox( <= ここ
           height: 80,
           width: 100,
           child: ListView(
             children: const [
               Text('真ん中に出てくるやつ'),
               Text('真ん中に出てくるやつ'),
               Text('真ん中に出てくるやつ'),
             ],
           ),
         ),
       );
     },
   );
 }

画像5


どちらもFlutterのBoxConstraints周りについて理解している(覚えていると)と遭遇しないであろう問題なので、そのうちBoxConstraintsについても記事を書こうと思います。


参考サイト

ISO(Online Browsing Platform):

   https://www.iso.org/obp/ui/#iso:std:iso:9241:-143:ed-1:en


この記事が気に入ったらサポートをしてみませんか?