Layout 颤振|如何在任何叠加上显示AlertDialog?

Layout 颤振|如何在任何叠加上显示AlertDialog?,layout,dart,flutter,overlay,Layout,Dart,Flutter,Overlay,如何始终在屏幕上的任何内容上方显示AlertDialog 代码: 导入“包装:颤振/材料.省道”; 类CountriesField扩展StatefulWidget{ @凌驾 _CountriesFieldState createState()=>U CountriesFieldState(); } 类_countries字段状态扩展状态{ 最终焦点节点_FocusNode=FocusNode(); 过度进入(OverlayEntry);; 最终层链接_LayerLink=LayerLink()

如何始终在屏幕上的任何内容上方显示AlertDialog

代码:

导入“包装:颤振/材料.省道”;
类CountriesField扩展StatefulWidget{
@凌驾
_CountriesFieldState createState()=>U CountriesFieldState();
}
类_countries字段状态扩展状态{
最终焦点节点_FocusNode=FocusNode();
过度进入(OverlayEntry);;
最终层链接_LayerLink=LayerLink();
@凌驾
void initState(){
_focusNode.addListener(){
if(_focusNode.hasFocus){
这个。_overlayEntry=这个。_createOverlayEntry();
覆盖.of(上下文).插入(本._覆盖入口);
}否则{
//这个._overlayEntry.remove();
}
});
}
OverlayEntry_createOverlayEntry(){
RenderBox RenderBox=context.findenderobject();
var size=renderBox.size;
返回重叠入口(
生成器:(上下文)=>已定位(
宽度:size.width,
子:复合传输功率(
链接:这个,
未链接时显示:false,
偏移量:偏移量(0.0,尺寸.高度+5.0),
儿童:材料(
标高:4.0,
子:ListView(
填充:EdgeInsets.zero,
收缩膜:对,
儿童:[
列表砖(
标题:文本(“叙利亚”),
onTap:(){
印刷品(‘叙利亚’);
},
),
列表砖(
标题:文本(“黎巴嫩”),
onTap:(){
印刷品(‘黎巴嫩’);
},
)
],
),
),
),
));
}
@凌驾
小部件构建(构建上下文){
返回复合传输目标(
链接:这个,
儿童:材料(
子项:TextFormField(
focusNode:这个,
装饰:输入装饰(标签文本:“国家”),
),
),
);
}
}
类FormPage扩展StatefulWidget{
@凌驾
_FormPageState createState()=>\u FormPageState();
}
类_FormPageState扩展了状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:专栏(
mainAxisAlignment:mainAxisAlignment.spaceAround,
儿童:[
材质(标高:4.0,子项:CountriesField()),
升起的按钮(
子项:文本(“帮助对话框”),
已按下:(){
显示对话框(
上下文:上下文,
生成器:(BuildContext上下文){
返回警报对话框(
标题:文本(“帮助”),
内容:文本(“应显示在任何叠加的顶部”),
行动:[
扁平按钮(
子项:文本(“关闭”),
已按下:(){
Navigator.of(context.pop();
},
),
],
);
});
},
)
],
),
);
}
}

没有简单的方法使对话框显示在覆盖层之上。根据您的用例,您可以将两者转换为
叠加
,或将两者转换为
对话框

这是使用
showDialog
方法将两者转换为对话框的示例:

当显示对话框时,您不必返回
AlertDialog
小部件,例如,在这里,我返回一个带有白色填充的
容器
,并且在后面包含一个用于“菜单a”对话框的
列表视图

使用
showDialog
时,您会自动获得一些功能,例如调暗背景并单击外部的任意位置以关闭。如果您不想使用这些或任何其他对话框内容,并且无法找到轻松禁用它们的方法,则始终可以使用另一种方法,将它们转换为
覆盖


对于覆盖,最新插入的将显示在顶部。

取消对行的注释-
//这。_overlayEntry.remove()-那没关系。@anmol.majhail我故意对其进行了评论,因为我正在寻找一个不需要删除覆盖项的一般答案。在某些小部件中,有必要不破坏覆盖。或者使用Navigator将覆盖入口替换为等效项。或者使用OverlayEntry将对话框替换为等效对话框
import 'package:flutter/material.dart';

class CountriesField extends StatefulWidget {
  @override
  _CountriesFieldState createState() => _CountriesFieldState();
}

class _CountriesFieldState extends State<CountriesField> {
  final FocusNode _focusNode = FocusNode();

  OverlayEntry _overlayEntry;

  final LayerLink _layerLink = LayerLink();

  @override
  void initState() {
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        this._overlayEntry = this._createOverlayEntry();
        Overlay.of(context).insert(this._overlayEntry);
      } else {
//        this._overlayEntry.remove();
      }
    });
  }

  OverlayEntry _createOverlayEntry() {
    RenderBox renderBox = context.findRenderObject();
    var size = renderBox.size;

    return OverlayEntry(
        builder: (context) => Positioned(
              width: size.width,
              child: CompositedTransformFollower(
                link: this._layerLink,
                showWhenUnlinked: false,
                offset: Offset(0.0, size.height + 5.0),
                child: Material(
                  elevation: 4.0,
                  child: ListView(
                    padding: EdgeInsets.zero,
                    shrinkWrap: true,
                    children: <Widget>[
                      ListTile(
                        title: Text('Syria'),
                        onTap: () {
                          print('Syria Tapped');
                        },
                      ),
                      ListTile(
                        title: Text('Lebanon'),
                        onTap: () {
                          print('Lebanon Tapped');
                        },
                      )
                    ],
                  ),
                ),
              ),
            ));
  }

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: this._layerLink,
      child: Material(
        child: TextFormField(
          focusNode: this._focusNode,
          decoration: InputDecoration(labelText: 'Country'),
        ),
      ),
    );
  }
}


class FormPage extends StatefulWidget {
  @override
  _FormPageState createState() => _FormPageState();
}

class _FormPageState extends State<FormPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Material(elevation: 4.0, child: CountriesField()),
          RaisedButton(
            child: Text('Help dialog'),
            onPressed: () {
              showDialog(
                  context: context,
                  builder: (BuildContext context) {
                    return AlertDialog(
                      title: Text("Help"),
                      content: Text("This should show on top of any overlay"),
                      actions: <Widget>[
                        FlatButton(
                          child: Text("Close"),
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                        ),
                      ],
                    );
                  });
            },
          )
        ],
      ),
    );
  }
}