我正在尝试在警报对话框中放置手势检测器以导航至下一页,但警报框溢出

时间:2019-09-24 05:29:17

标签: android flutter dart flutter-layout

我没有在警报对话框中使用任何按钮,因此在动作中,如果我们正在使用手势检测器或墨水池来获得点按或按动功能,或者有任何功能,我们如何防止警报对话框溢出另一种方法

  _showDialog(BuildContext context) {
   showDialog(
    context: context,
    builder: (context) {
      return UnicornAlertDialog(
          title: Column(
            children: <Widget>[
              Container(
                child: Image.asset('images/done.png'),
              ),
              const SizedBox(height: 15.0),
              Container(
                child: Text(
                  'Verify',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 20.0,
                  ),
                ),
              )
            ],
          ),
          content: Text('You have successfully verified your mobile number',
              textAlign: TextAlign.center,
              style: TextStyle(color: Colors.white, fontSize: 15.0)),
          gradient: LinearGradient(
            colors: <Color>[
              Color(0xDD4a00e0),
              Color(0xFF8e2de2),
            ],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
          ),
          actions: <Widget>[
            Container(
              child: new GestureDetector(

                onTap:(){
                Navigator.push(context,
                    MaterialPageRoute(builder: (context) => ThirdRoute()));

                } ,
              ),
            ),

          ]
          );
    });
 }

3 个答案:

答案 0 :(得分:0)

由于对话框的overflow error属性内使用了GestureDetector,因此您得到actions。如果只希望用户在alertDialog上的任意位置点击,则可以将AlertDialogGestureDetector包装在一起。这样,当用户在对话框上的任意位置点击时,它将导航至thirdRoute。下面的工作代码:

_showDialog(BuildContext context) {
    showDialog(
        context: context,
        builder: (context) {
          return GestureDetector(
            child: AlertDialog(
                title:
                Column(
                  children: <Widget>[
                    Container(
                      child: Image.asset('images/done.png'),
                    ),
                      const SizedBox(height: 15.0),
                    Container(
                      child: Text(
                        'Verify',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.black,
                          fontSize: 20.0,
                        ),
                      ),
                    )
                  ],
                ),
                content:
                Text('You have successfully verified your mobile number',
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.black, fontSize: 15.0)),
//              gradient: LinearGradient(
//                colors: <Color>[
//                  Color(0xDD4a00e0),
//                  Color(0xFF8e2de2),
//                ],
//                begin: Alignment.topCenter,
//                end: Alignment.bottomCenter,
//              ),
                actions: <Widget>[]
            ),
            onTap: () {
              Navigator.push(context, MaterialPageRoute(builder: (context) => NextScreen()));
            }
          );
        });
  }

希望这能回答您的问题。

答案 1 :(得分:0)

      _showDialog(BuildContext context) {
showDialog(
    context: context,
    builder: (context) {
      return GestureDetector(
        child: UnicornAlertDialog(
            title: Column(
              children: <Widget>[
                Container(
                  child: Image.asset('images/done.png'),
                ),
                const SizedBox(height: 15.0),
                Container(
                  child: Text(
                    'Verify',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20.0,
                    ),
                  ),
                )
              ],
            ),
            content: Text(
                'You have successfully verified your mobile number',
                textAlign: TextAlign.center,
                style: TextStyle(color: Colors.white, fontSize: 15.0)),
            gradient: LinearGradient(
              colors: <Color>[
                Color(0xDD4a00e0),
                Color(0xFF8e2de2),
              ],
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
            actions: <Widget>[ ]),
        onTap: () {
          Navigator.push(context,
              MaterialPageRoute(builder: (context) => ThirdRoute()));
        },
      );
    });
   }

独角兽警报对话框用于装饰背景颜色,由于在常规警报对话框中不能使用渐变颜色,因此我使用了它。

答案 2 :(得分:0)

代码段

_showDialog(BuildContext context) {
  showDialog(
      context: context,
      builder: (context) {
        return UnicornAlertDialog(
            title: GestureDetector(
              onTap: () { print("on tap title");},
              child: Column(
                children: <Widget>[
                  Container(
                    child: Image.asset('assets/images/background.jpg'),
                  ),
                  const SizedBox(height: 15.0),
                  Container(
                    child: Text(
                      'Verify',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                      ),
                    ),
                  )
                ],
              ),
            ),
            content: GestureDetector(
              onTap: () { print("on tap content");},
              child: Text('You have successfully verified your mobile number',
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.white, fontSize: 15.0)),
            ),
            gradient: LinearGradient(
              colors: <Color>[
                Color(0xDD4a00e0),
                Color(0xFF8e2de2),
              ],
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
            actions: <Widget>[


            ]
        );
      });
}

完整代码

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';

class UnicornAlertDialog extends StatelessWidget {
  const UnicornAlertDialog({
    Key key,
    @required this.gradient,
    this.title,
    this.titlePadding,
    this.titleTextStyle,
    this.content,
    this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0),
    this.contentTextStyle,
    this.actions,
    this.backgroundColor,
    this.elevation,
    this.semanticLabel,
    this.shape,
  })  : assert(contentPadding != null),
        super(key: key);

  final Gradient gradient;
  final Widget title;
  final EdgeInsetsGeometry titlePadding;
  final TextStyle titleTextStyle;
  final Widget content;
  final EdgeInsetsGeometry contentPadding;
  final TextStyle contentTextStyle;
  final List<Widget> actions;
  final Color backgroundColor;
  final double elevation;
  final String semanticLabel;
  final ShapeBorder shape;

  @override
  Widget build(BuildContext context) {
    assert(debugCheckHasMaterialLocalizations(context));
    final ThemeData theme = Theme.of(context);
    final DialogTheme dialogTheme = DialogTheme.of(context);
    final List<Widget> children = <Widget>[];
    String label = semanticLabel;

    if (title != null) {
      children.add(Padding(
        padding: titlePadding ?? EdgeInsets.fromLTRB(24.0, 24.0, 24.0, content == null ? 20.0 : 0.0),
        child: DefaultTextStyle(
          style: titleTextStyle ?? dialogTheme.titleTextStyle ?? theme.textTheme.title,
          child: Semantics(
            child: title,
            namesRoute: true,
            container: true,
          ),
        ),
      ));
    } else {
      switch (defaultTargetPlatform) {
        case TargetPlatform.iOS:
          label = semanticLabel;
          break;
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
          label = semanticLabel ?? MaterialLocalizations.of(context)?.alertDialogLabel;
      }
    }

    if (content != null) {
      children.add(Flexible(
        child: Padding(
          padding: contentPadding,
          child: DefaultTextStyle(
            style: contentTextStyle ?? dialogTheme.contentTextStyle ?? theme.textTheme.subhead,
            child: content,
          ),
        ),
      ));
    }

    if (actions != null) {
      children.add(ButtonTheme.bar(
        child: ButtonBar(
          children: actions,
        ),
      ));
    }

    Widget dialogChild = IntrinsicWidth(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: children,
      ),
    );

    if (label != null)
      dialogChild = Semantics(
        namesRoute: true,
        label: label,
        child: dialogChild,
      );

    return Dialog(
      backgroundColor: backgroundColor,
      gradient: gradient,
      elevation: elevation,
      shape: shape,
      child: dialogChild,
    );
  }
}

class Dialog extends StatelessWidget {
  const Dialog({
    Key key,
    this.gradient,
    this.backgroundColor,
    this.elevation,
    this.insetAnimationDuration = const Duration(milliseconds: 100),
    this.insetAnimationCurve = Curves.decelerate,
    this.shape,
    this.child,
  }) : super(key: key);

  final Color backgroundColor;
  final double elevation;
  final Duration insetAnimationDuration;
  final Curve insetAnimationCurve;
  final ShapeBorder shape;
  final Widget child;
  final Gradient gradient;

  static const RoundedRectangleBorder _defaultDialogShape =
  RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)));
  static const double _defaultElevation = 24.0;

  @override
  Widget build(BuildContext context) {
    final DialogTheme dialogTheme = DialogTheme.of(context);
    return AnimatedPadding(
      padding: MediaQuery.of(context).viewInsets + const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0),
      duration: insetAnimationDuration,
      curve: insetAnimationCurve,
      child: MediaQuery.removeViewInsets(
        removeLeft: true,
        removeTop: true,
        removeRight: true,
        removeBottom: true,
        context: context,
        child: Center(
          child: ConstrainedBox(
            constraints: const BoxConstraints(minWidth: 280.0),
            child: Material(
              color: backgroundColor ?? dialogTheme.backgroundColor ?? Theme.of(context).dialogBackgroundColor,
              elevation: elevation ?? dialogTheme.elevation ?? _defaultElevation,
              shape: shape ?? dialogTheme.shape ?? _defaultDialogShape,
              type: MaterialType.card,
              child: ClipRRect(
                borderRadius: _defaultDialogShape.borderRadius,
                child: Container(
                  decoration: BoxDecoration(
                      gradient: gradient
                  ),
                  child: child,
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}



_showDialog(BuildContext context) {
  showDialog(
      context: context,
      builder: (context) {
        return UnicornAlertDialog(
            title: GestureDetector(
              onTap: () { print("on tap title");},
              child: Column(
                children: <Widget>[
                  Container(
                    child: Image.asset('assets/images/background.jpg'),
                  ),
                  const SizedBox(height: 15.0),
                  Container(
                    child: Text(
                      'Verify',
                      textAlign: TextAlign.center,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 20.0,
                      ),
                    ),
                  )
                ],
              ),
            ),
            content: GestureDetector(
              onTap: () { print("on tap content");},
              child: Text('You have successfully verified your mobile number',
                  textAlign: TextAlign.center,
                  style: TextStyle(color: Colors.white, fontSize: 15.0)),
            ),
            gradient: LinearGradient(
              colors: <Color>[
                Color(0xDD4a00e0),
                Color(0xFF8e2de2),
              ],
              begin: Alignment.topCenter,
              end: Alignment.bottomCenter,
            ),
            actions: <Widget>[


            ]
        );
      });
}



Future<void> _ackAlert(BuildContext context) {
  return showDialog<void>(
    context: context,
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Not in stock'),
        content: const Text('This item is no longer available'),
        actions: <Widget>[
          FlatButton(
            child: Text('Ok'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
        ],
      );
    },
  );
}
enum ConfirmAction { CANCEL, ACCEPT }
Future<ConfirmAction> _asyncConfirmDialog(BuildContext context) async {
  return showDialog<ConfirmAction>(
    context: context,
    barrierDismissible: false, // user must tap button for close dialog!
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Reset settings?'),
        content: const Text(
            'This will reset your device to its default factory settings.'),
        actions: <Widget>[
          FlatButton(
            child: const Text('CANCEL'),
            onPressed: () {
              Navigator.of(context).pop(ConfirmAction.CANCEL);
            },
          ),
          FlatButton(
            child: const Text('ACCEPT'),
            onPressed: () {
              Navigator.of(context).pop(ConfirmAction.ACCEPT);
            },
          )
        ],
      );
    },
  );
}

Future<String> _asyncInputDialog(BuildContext context) async {
  String teamName = '';
  return showDialog<String>(
    context: context,
    barrierDismissible: false, // dialog is dismissible with a tap on the barrier
    builder: (BuildContext context) {
      return AlertDialog(
        title: Text('Enter current team'),
        content: new Row(
          children: <Widget>[
            new Expanded(
                child: new TextField(
                  autofocus: true,
                  decoration: new InputDecoration(
                      labelText: 'Team Name', hintText: 'eg. Juventus F.C.'),
                  onChanged: (value) {
                    teamName = value;
                  },
                ))
          ],
        ),
        actions: <Widget>[
          FlatButton(
            child: Text('Ok'),
            onPressed: () {
              Navigator.of(context).pop(teamName);
            },
          ),
        ],
      );
    },
  );
}

enum Departments { Production, Research, Purchasing, Marketing, Accounting }

Future<Departments> _asyncSimpleDialog(BuildContext context) async {
  return await showDialog<Departments>(
      context: context,
      barrierDismissible: true,
      builder: (BuildContext context) {
        return SimpleDialog(
          title: const Text('Select Departments '),
          children: <Widget>[
            SimpleDialogOption(
              onPressed: () {
                Navigator.pop(context, Departments.Production);
              },
              child: const Text('Production'),
            ),
            SimpleDialogOption(
              onPressed: () {
                Navigator.pop(context, Departments.Research);
              },
              child: const Text('Research'),
            ),
            SimpleDialogOption(
              onPressed: () {
                Navigator.pop(context, Departments.Purchasing);
              },
              child: const Text('Purchasing'),
            ),
            SimpleDialogOption(
              onPressed: () {
                Navigator.pop(context, Departments.Marketing);
              },
              child: const Text('Marketing'),
            ),
            SimpleDialogOption(
              onPressed: () {
                Navigator.pop(context, Departments.Accounting);
              },
              child: const Text('Accounting'),
            )
          ],
        );
      });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: AppBar(
        title: Text("Dialog"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new RaisedButton(
              onPressed: () {
                _showDialog(context);
              },
              child: const Text("Unicon Dialog"),
            ),
            new RaisedButton(
              onPressed: () {
                _ackAlert(context);
              },
              child: const Text("Ack Dialog"),
            ),
            new RaisedButton(
              onPressed: () async {
                final ConfirmAction action = await _asyncConfirmDialog(context);
                print("Confirm Action $action" );
              },
              child: const Text("Confirm Dialog"),
            ),
            new RaisedButton(
              onPressed: () async {
                final Departments deptName = await _asyncSimpleDialog(context);
                print("Selected Departement is $deptName");
              },
              child: const Text("Simple dialog"),
            ),
            new RaisedButton(
              onPressed: () async {
                final String currentTeam = await _asyncInputDialog(context);
                print("Current team name is $currentTeam");
              },
              child: const Text("Input Dialog"),
            ),
          ],
        ),
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(home: new MyApp()));
}

enter image description here