颤振如何在任何覆盖图的顶部显示AlertDialog?

时间:2019-02-07 07:20:35

标签: layout dart flutter overlay

如何始终将AlertDialog显示在屏幕上的任何内容之上?

enter image description here

代码:

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();
                          },
                        ),
                      ],
                    );
                  });
            },
          )
        ],
      ),
    );
  }
}

1 个答案:

答案 0 :(得分:0)

没有简单的方法可以使对话框出现在叠加层的顶部。根据您的用例,您可以将两者都转换为Overlay,也可以将两者都转换为Dialog

这是一个使用showDialog方法将它们都转换为对话框的示例:

demo

显示对话框时,您不必返回AlertDialog小部件,例如,这里我返回的是带有白色填充的Container,其中包含一个ListView后面的“菜单A”对话框。

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

对于叠加层,以最新插入的为准。