flutter自定義dialog 實現寬度自定義 界面自定義

效果

在這裏插入圖片描述

大致思路

1、彈框整體實現 和寫界面是一樣的 畢竟flutter中 一切皆組件 界面 彈框 按鈕。。。。都是組件
2、樣式和跳轉要進行處理 背景色透明效果有兩種實現方式
a、界面跳轉中opaque: false可以設置下個界面背景透明
b、使用showDialog進行新界面跳轉
3、佈局中使用Material type: MaterialType.transparency設置爲背景透明

dialog相關代碼
///* 作者:guoyzh
///* 時間:2020/1/6
///* 功能:自定義dialog的抽取

class BaseDialog extends StatefulWidget {
  final String title;
  final String content;
  final bool cancelAble;
  final Function confirmCallback; // 點擊確定按鈕回調
  final Function cancelCallback; // 點擊取消按鈕
  final Function dismissCallback; // 彈窗關閉回調

  BaseDialog(
      {this.title = "",
      this.content = "",
      this.cancelAble = true,
      this.confirmCallback,
      this.cancelCallback,
      this.dismissCallback});

  @override
  _BaseDialogState createState() => _BaseDialogState();
}

class _BaseDialogState extends State<BaseDialog> {
  @override
  Widget build(BuildContext context) {
    // 設置彈框的寬度爲屏幕寬度的86%
    var _dialogWidth = MediaQuery.of(context).size.width * 0.86;

    // 構建彈框內容
    Container _dialogContent = Container(
      decoration: ShapeDecoration(
        color: Color(0xffffffff),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.all(
            Radius.circular(4.0),
          ),
        ),
      ),
      child: Column(
        // 主軸對齊方向
        mainAxisAlignment: MainAxisAlignment.center,
        // 另一個軸對齊方向
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          // 標題
          Padding(
            padding: const EdgeInsets.fromLTRB(30, 0, 0, 0),
            child: Text(
              widget.title == "" ? "標題" : widget.title,
              style: TextStyle(
                  color: Colors.black,
                  fontSize: 24,
                  fontWeight: FontWeight.w300),
            ),
          ),
          // 內容
          Padding(
            padding: const EdgeInsets.fromLTRB(30, 12, 0, 0),
            child: Text(
              widget.content == "" ? "內容" : widget.content,
              style: TextStyle(
                color: Colors.black,
                fontSize: 18,
              ),
            ),
          ),
          // 按鈕
          Row(
            children: <Widget>[
              GestureDetector(
                onTap: _clickCancel,
                child: Padding(
                  padding: const EdgeInsets.fromLTRB(146, 26, 0, 0),
                  child: Text(
                    "取消",
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 18,
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onTap: _clickConfirm,
                child: Padding(
                  padding: EdgeInsets.fromLTRB(52, 26, 0, 0),
                  child: Text(
                    "確定",
                    style: TextStyle(
                      color: Color.fromRGBO(233, 87, 14, 1),
                      fontSize: 18,
                    ),
                  ),
                ),
              ),
            ],
          )
        ],
      ),
    );

    // 構建彈框佈局
    return WillPopScope(
        child: GestureDetector(
          onTap: () => {widget.cancelAble ? _dismissDialog() : null},
          child: Material(
            type: MaterialType.transparency,
            child: Center(
              //保證控件居中效果
              child: SizedBox(
                // 設置彈框寬度
                width: _dialogWidth,
                height: 186.0,
                child: _dialogContent,
              ),
            ),
          ),
        ),
        onWillPop: () async {
          return widget.cancelAble;
        });
  }

  /// 點擊隱藏dialog
  _dismissDialog() {
    if (widget.dismissCallback != null) {
      widget.dismissCallback();
    }
    Navigator.of(context).pop();
  }

  /// 點擊取消
  void _clickCancel() {
    if (widget.confirmCallback != null) {
      widget.confirmCallback();
    }
    _dismissDialog();
  }

  /// 點擊確定
  void _clickConfirm() {
    if (widget.confirmCallback != null) {
      widget.confirmCallback();
    }
    _dismissDialog();
  }
}
展示彈框工具類方法
/// 展示dialog
static void showDialogs(BuildContext context, Widget dialog) {
  // 導航到新路由 背景顏色爲透明色
  /*Navigator.of(context).push(PageRouteBuilder(
      opaque: false,
      pageBuilder: (context, animation, secondaryAnimation) {
        return dialog;
      }));*/
  showDialog(context: context, builder: (_) => dialog);
}
代碼中調用
AppUtils.showDialogs(context, BaseDialog(title: '提示', content: '確認退出?'));
發佈了200 篇原創文章 · 獲贊 97 · 訪問量 59萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章