Flutter 23: 圖解自定義 Dialog 對話方塊

funnyok發表於2021-09-09

       在我們的日常開發中是必不可少的,Flutter 也提供了 / 供我們選擇,但是對於開發還是不足夠的,小菜嘗試了一下自定義對話方塊,簡單記錄一下。

1. 繼承 Dialog

      Dialog 只是一個基礎的 Widget 不會直接使用,小菜想自定義 Dialog 必須先繼承 Dialog。此時需要重寫 Widget build(BuildContext context) 方法。

2. 繪製 Dialog 樣式

      小菜嘗試做一個性別選擇框,包括標題,圖片和按鈕等。

import 'package:flutter/material.dart';class GenderChooseDialog extends Dialog {
  GenderChooseDialog({
    Key key,
  }) : super(key: key);  @override
  Widget build(BuildContext context) {    return new Padding(
        padding: const EdgeInsets.all(12.0),
        child: new Material(
            type: MaterialType.transparency,
            child: new Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[                  new Container(
                      decoration: ShapeDecoration(
                          color: Color(0xFFFFFFFF),
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.all(
                            Radius.circular(8.0),
                          ))),
                      margin: const EdgeInsets.all(12.0),
                      child: new Column(children: <Widget>[                        new Padding(
                            padding: const EdgeInsets.fromLTRB(                                10.0, 40.0, 10.0, 28.0),
                            child: Center(
                                child: new Text('請選擇性別',
                                    style: new TextStyle(
                                      fontSize: 20.0,
                                    )))),                        new Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            mainAxisSize: MainAxisSize.max,
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: <Widget>[
                              _genderChooseItemWid(1),
                              _genderChooseItemWid(2)
                            ])
                      ]))
                ])));
  }  Widget _genderChooseItemWid(var gender) {    return GestureDetector(
        child: Column(children: <Widget>[
      Image.asset(
          gender == 1
              ? 'images/icon_type_boy.png'
              : 'images/icon_type_girl.png',
          width: 135.0,
          height: 135.0),
      Padding(
          padding: EdgeInsets.fromLTRB(0.0, 22.0, 0.0, 40.0),
          child: Text(gender == 1 ? '我是男生' : '我是女生',
              style: TextStyle(
                  color: Color(gender == 1 ? 0xff4285f4 : 0xffff4444),
                  fontSize: 15.0)))
    ]));
  }
}

圖片描述

3. 內容傳參

      小菜儘量把對話方塊做到通用性強一些,小菜測試僅把標題當引數傳遞,一個引數與多個引數是類似的。

class GenderChooseDialog extends Dialog {
  
  var title;
  
  GenderChooseDialog({
    Key key,    @required this.title,
  }) : super(key: key);  @override
  Widget build(BuildContext context) { }
}

4. 新增點選事件

      每個對話方塊要有自己的點選事件,小菜準備把點選不同圖片或文字時新增不同的點選事件。需要自定義 Function 方法。

class GenderChooseDialog extends Dialog {
  var title;
  Function onBoyChooseEvent;
  Function onGirlChooseEvent;

  GenderChooseDialog({
    Key key,    @required this.title,    @required this.onBoyChooseEvent,    @required this.onGirlChooseEvent,
  }) : super(key: key);  
  Widget _genderChooseItemWid(var gender) {    return GestureDetector(
        onTap: gender == 1 ? this.onBoyChooseEvent : this.onGirlChooseEvent,
        child: Column(children: <Widget>[
          Image.asset(
              gender == 1 ? 'images/icon_type_boy.png'
                  : 'images/icon_type_girl.png',
              width: 135.0, height: 135.0),
          Padding(
              padding: EdgeInsets.fromLTRB(0.0, 22.0, 0.0, 40.0),
              child: Text(gender == 1 ? '我是男生' : '我是女生',
                  style: TextStyle(
                      color: Color(gender == 1 ? 0xff4285f4 : 0xffff4444),
                      fontSize: 15.0)))
        ]));
  }
}// 方法呼叫void _onItemPressed() {
  showDialog(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {        return GenderChooseDialog(
            title: '小哥哥小姐姐請選擇',
            onBoyChooseEvent: () {
              Navigator.pop(context);
            },
            onGirlChooseEvent: () {
              Navigator.pop(context);
            });
      });
}

圖片描述

5. 注意事項

  1. Dialog 也是 Widget 預設是佔滿全屏,所以小菜自己繪製部分對話方塊,為了協調,藉助 type: MaterialType.transparency 設定了對話方塊外半透明效果;

  2. 無論是傳參還是設定點選事件,都需要在初始化中新增,很像 Android 中對 RecycleView 設定內容和點選事件等;

GenderChooseDialog({
  Key key,  @required this.title,  @required this.onBoyChooseEvent,  @required this.onGirlChooseEvent,
}) : super(key: key);
  1. showDialog 方法中,barrierDismissible: false 屬性代表點選頂部狀態列(顯示電量/時間的橫條位置)時是否關閉對話方塊,如果想點選半透明位置時關閉對話方塊,可以再新增一個點選事件即可。



作者:阿策神奇


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2822464/,如需轉載,請註明出處,否則將追究法律責任。

相關文章