實現Flutter彈窗的正確姿勢..

CoorChice發表於2019-04-15

目錄傳送門:《Flutter快速上手指南》先導篇

Dialog 在現代的視覺互動中是很常用的一種 UI。

做移動端開發的同學一定對它不陌生。

本篇將會探索一下,在 Flutter 中如何構建一個 Dialog UI。

1.如何展示一個Dialog?

1.匯入 material 外掛

'package:flutter/material.dart'
複製程式碼

2.呼叫 showDialog() 來展示一個 Dialog

Future<T> showDialog<T>({
  @required BuildContext context,
  // 點選 dialog 外部是否可消失
  bool barrierDismissible = true,
  // 構建 Dialog 檢視
  WidgetBuilder builder,
})
複製程式碼

沒錯,只需要呼叫這個簡單的函式就可以展示一個 Dialog。

重點是,在 builder 中構建你的 Dialog 檢視。

這是一個簡單的例子:

showDialog(
  // 傳入 context
  context: context,
  // 構建 Dialog 的檢視
  builder: (_) => Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Container(
              alignment: Alignment.center,
              color: Colors.white,
              child: Column(
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.only(top: 8),
                    child: Text('Custom Dialog',
                        style: TextStyle(
                            fontSize: 16,
                            decoration: TextDecoration.none)),
                  ),
                  Padding(
                    padding: EdgeInsets.only(top: 15, bottom: 8),
                    child: FlatButton(
                        onPressed: () {
                          // 關閉 Dialog
                          Navigator.pop(_);
                        },
                        child: Text('確定')),
                  )
                ],
              ),
            )
          ],
        ),
      ),
);
複製程式碼

看看效果:

其實和平時構建一個頁面沒多大區別,只不過是在 showDialog()builder 中構建。

如果你注意細節的話,你會發現上面程式碼中有一行:

Navigator.pop(_);
複製程式碼

它就是用來關閉 Dialog 的操作。

還記得 Navigator 嗎?

它是用來進行頁面跳轉的,也許你可以看看 《8.頁面跳轉》 來回顧回顧。

這意味著,彈出一個 Dialog,實際上就是開啟了一個 Dialog 風格的頁面!!?

跟蹤原始碼會發現,在 showDialog() 的最後實現中,實際是這樣的:

Navigator.of(context, rootNavigator: true).push<T>(_DialogRoute<T>(
    pageBuilder: pageBuilder,
    barrierDismissible: barrierDismissible,
    barrierLabel: barrierLabel,
    barrierColor: barrierColor,
    transitionDuration: transitionDuration,
    transitionBuilder: transitionBuilder,
  ))
複製程式碼

? 可不就是開啟了一個頁面嘛..

2.常用 Dialog

Flutter 當然會提供一些 Dialog 的封裝,幫助開發者快速的構建常用的 Dialog。

2.1 SimpleDialog

先看看 SimpleDialog 有些什麼常用引數:

屬性型別說明
titleWidgetDialog的標題
titlePaddingEdgeInsetsGeometrytitle周圍的 Padding
childrenListchild內容陣列,會從上到下的排列 child
contentPaddingEdgeInsetsGeometry內容區域周圍的 Padding
backgroundColorColorDialog的背景色
elevationdoubleDialog 的懸浮高度,和陰影效果有關
shapeShapeBorderDialog的邊框形狀

? e.g.:

showDialog(
  context: context,
  builder: (ctx) {
    return SimpleDialog(
      title: Text("SimpleDialog"),
      titlePadding: EdgeInsets.all(10),
      backgroundColor: Colors.amber,
      elevation: 5,
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(Radius.circular(6))),
      children: <Widget>[
        ListTile(
          title: Center(child: Text("Item_1"),),
        ),
        ListTile(
          title: Center(child: Text("Item_2"),),
        ),
        ListTile(
          title: Center(child: Text("Item_3"),),
        ),
        ListTile(
          title: Center(child: Text("Close"),),
          onTap: (){
            Navigator.pop(context);
          },
        ),
      ],
    );
  });
複製程式碼

? 看看是啥效果:

2.2 AlertDialog

上圖中的 Dialog 樣式是現在比較常用的。

Flutter 幫助我們封裝了 AlertDialog 來方便的實現這種樣式。

看看 AlertDialog 有哪些常用的屬性:

屬性型別說明
titleWidgetDialog的標題
titlePaddingEdgeInsetsGeometrytitle周圍的 Padding
contentWidgetDialog 中間的內容
contentPaddingEdgeInsetsGeometry內容區域周圍的 Padding
backgroundColorColorDialog的背景色
elevationdoubleDialog 的懸浮高度,和陰影效果有關
shapeShapeBorderDialog的邊框形狀
actionsList通常為Dialog底部的操作按鈕

? e.g.:

showDialog(
  context: context,
  builder: (context) => AlertDialog(
        title: Text('Dialog'),
        content: Text(('Dialog content..')),
        actions: <Widget>[
          new FlatButton(
            child: new Text("取消"),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          new FlatButton(
            child: new Text("確定"),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ],
      ));
複製程式碼

這就是上圖中的 Dialog 的實現。

目錄傳送門:《Flutter快速上手指南》先導篇

如何找到我?

傳送門:CoorChice 的主頁

傳送門:CoorChice 的 Github


相關文章