Flutter 重構:基於 PopupRoute 的極簡彈窗

SoaringHeart發表於2021-07-30

這可能是顆粒度最好的 PopupRoute 彈窗封裝。

核心:

Flutter 需要自定義各式各樣的彈窗檢視,總是有些場景系統提供的無法滿足需求,隨使用彈出路由 PopupRoute 進行封裝;核心是繼承 PopupRoute 進行容器化封裝,將 檢視 child 抽出,使用者可以傳入任意 Widget, 通過 Alignment 調整 child 檢視顯示位置;

  final title1 = "曼德拉《漫漫人生路》";
  final message1 = """
如果發出聲音是危險的,那就保持沉默;
如果自覺無力發光,那就別去照亮別人。
但是——不要習慣了黑暗就為黑暗辯護;
不要為自己的苟且而得意洋洋;
不要嘲諷那些比自己更勇敢、更有熱量的人們。
我們可以卑微如塵土,不可扭曲如蛆蟲。
——曼德拉《漫漫人生路》
""";
複製程式碼

效果 - 仿 AlertDialog

Navigator.push(context,
  NNPopupRoute(
    alignment: Alignment.topCenter,
    onClick: () {
      ddlog("exit");
      //點選空白處
      Navigator.of(context).pop();
    },
    // child: buildAlertColumn(context, marginHor: 15),
    child: NNAlertDialog(
      marginHor: 10,
      title: Text(title1, style: TextStyle(fontWeight: FontWeight.w500),),
      content: Text(message1, style: TextStyle(fontWeight: FontWeight.w300),),
      actionCancell: TextButton(
        onPressed: () {
          ddlog("取消");
          Navigator.of(context).pop();
          },
        child: Text("取消"),
      ),
      actionConfirm: TextButton(
        onPressed: () {
          ddlog("確定");
          Navigator.of(context).pop();
        },
        child: Text("確定"),
      ),
    ),
  ),
);
複製程式碼

Simulator Screen Shot - iPhone 11 Pro - 2021-07-30 at 14.18.44.png


//...
NNPopupRoute(
  alignment: Alignment.bottomCenter,
//...
複製程式碼

Simulator Screen Shot - iPhone 11 Pro - 2021-07-30 at 14.21.04.png


Navigator.push(context,
  NNPopupRoute(
    // alignment: Alignment.topCenter,
    onClick: () {
      ddlog("exit");
      //點選空白處
      Navigator.of(context).pop();
    },
    // child: buildAlertColumn(context, marginHor: 15),
    child: NNAlertDialog(
      marginHor: 10,
      title: Text(title1, style: TextStyle(fontWeight: FontWeight.w500),),
      content: Text(message1, style: TextStyle(fontWeight: FontWeight.w300),),
      actions: ["選擇A", "選擇B", "選擇C", "選擇D"].map((e) => TextButton(onPressed: (){
        ddlog(e);
        Navigator.pop(context);
      }, child: Text(e),)).toList(),
    ),
  ),
);
複製程式碼

Simulator Screen Shot - iPhone 11 Pro - 2021-07-30 at 14.19.11.png


//...
NNPopupRoute(
  alignment: Alignment.bottomCenter,
//...
複製程式碼

Simulator Screen Shot - iPhone 11 Pro - 2021-07-30 at 14.20.50.png


效果 - 仿通知訊息檢視

final screenSize = MediaQuery.of(context).size;

double spacingVer = 8;
double spacingHor = 15;

Navigator.push(context,
  NNPopupRoute(
    alignment: Alignment.topCenter,
    onClick: () {
      ddlog("exit");
      //點選空白處
      Navigator.of(context).pop();
    },
    // child: buildAlertColumn(context, marginHor: 15),
    child: GestureDetector(
      onTap: (){
          ddlog("tap Container");
        },
      child: Container(
        width: screenSize.width - 10,
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular((10.0)), // 圓角度
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Padding(
              padding: EdgeInsets.only(top: spacingVer, left: spacingHor, bottom: spacingVer, right: spacingHor),
              child: Text(title1, style: TextStyle(fontWeight: FontWeight.w600),),
            ),
            Padding(
              padding: EdgeInsets.only(left: spacingHor, bottom: spacingVer, right: spacingHor),
              child: Text(message1, style: TextStyle(fontWeight: FontWeight.w300),),
            ),
          ],
        ),
      ),
    ),
  ),
);
複製程式碼

Simulator Screen Shot - iPhone 11 Pro - 2021-07-30 at 14.38.14.png

NNPopupRoute.dart

NNAlertDialog.dart

相關文章