如何在颤动中制作全屏对话框?

Sab*_*r33 23 dart flutter

我想制作一个全屏对话框.对话框背景必须是不透明的.这是一个例子: 在此输入图像描述

如何在Flutter中制作这样的?

bof*_*mer 36

您可以使用Navigator推动半透明ModalRoute:

import 'package:flutter/material.dart';

class TutorialOverlay extends ModalRoute<void> {
  @override
  Duration get transitionDuration => Duration(milliseconds: 500);

  @override
  bool get opaque => false;

  @override
  bool get barrierDismissible => false;

  @override
  Color get barrierColor => Colors.black.withOpacity(0.5);

  @override
  String get barrierLabel => null;

  @override
  bool get maintainState => true;

  @override
  Widget buildPage(
      BuildContext context,
      Animation<double> animation,
      Animation<double> secondaryAnimation,
      ) {
    // This makes sure that text and other content follows the material style
    return Material(
      type: MaterialType.transparency,
      // make sure that the overlay content is not cut off
      child: SafeArea(
        child: _buildOverlayContent(context),
      ),
    );
  }

  Widget _buildOverlayContent(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(
            'This is a nice overlay',
            style: TextStyle(color: Colors.white, fontSize: 30.0),
          ),
          RaisedButton(
            onPressed: () => Navigator.pop(context),
            child: Text('Dismiss'),
          )
        ],
      ),
    );
  }

  @override
  Widget buildTransitions(
      BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
    // You can add your own animations for the overlay content
    return FadeTransition(
      opacity: animation,
      child: ScaleTransition(
        scale: animation,
        child: child,
      ),
    );
  }
}


// Example application:
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Playground',
      home: TestPage(),
    );
  }
}

class TestPage extends StatelessWidget {
  void _showOverlay(BuildContext context) {
    Navigator.of(context).push(TutorialOverlay());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Test')),
      body: Padding(
        padding: EdgeInsets.all(16.0),
        child: Center(
          child: RaisedButton(
            onPressed: () => _showOverlay(context),
            child: Text('Show Overlay'),
          ),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


Muh*_*dil 21

好吧,这是我的实现,非常简单。

从第一个屏幕

Navigator.of(context).push(PageRouteBuilder(
    opaque: false,
    pageBuilder: (BuildContext context, _, __) =>
        RedeemConfirmationScreen()));
Run Code Online (Sandbox Code Playgroud)

在第二屏

class RedeemConfirmationScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
  backgroundColor: Colors.white.withOpacity(0.85), // this is the main reason of transparency at next screen. I am ignoring rest implementation but what i have achieved is you can see.
.....
  );
 }
}
Run Code Online (Sandbox Code Playgroud)

这是结果。

在此处输入图片说明


Bar*_*ker 8

注意:此答案没有讨论使模态透明,而是针对陈述的问题“如何在颤动中进行全屏对话框?”。希望这可以帮助其他人像我一样通过搜索找到该问题,而这些人不需要透明的模态。

创建模态对话框类:

class SomeDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Dialog Magic'),
      ),
      body: new Text("It's a Dialog!"),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在需要打开对话框的类中,添加以下内容:

void openDialog() {
  Navigator.of(context).push(new MaterialPageRoute<Null>(
    builder: (BuildContext context) {
      return new SomeDialog();
    },
    fullscreenDialog: true));
}
Run Code Online (Sandbox Code Playgroud)

如果需要获取对话框操作的结果,请在对话框中添加一个按钮,该按钮在弹出导航堆栈时会返回一个值。像这样:

onPressed: () {
  Navigator
    .of(context)
    .pop(new MyReturnObject("some value");
}
Run Code Online (Sandbox Code Playgroud)

然后在您的类中打开对话框,使用以下内容捕获结果:

void openDialog() async {
  MyReturnObject results = await Navigator.of(context).push(new MaterialPageRoute<MyReturnObject>(
    builder: (BuildContext context) {
      return new SomeDialog();
    },
    fullscreenDialog: true));
}
Run Code Online (Sandbox Code Playgroud)

  • 这不起作用 - 我看到白色屏幕上有项目。不透明 (3认同)
  • @GuilhermeMatuella,如果你在谷歌中输入“全屏对话框颤动”,这个页面将是第一个点击,这就是我来这里的原因。在上面的第一段中,他明确表示答案没有解决问题的半透明部分。 (2认同)

Cop*_*oad 5

输出(使用flutter的本机对话框)

在此处输入图片说明

这是使用flutter内置方法显示对话框的方式showGeneralDialog。想要显示对话框的任何地方都调用此方法。

showGeneralDialog(
  context: context,
  barrierColor: Colors.black12.withOpacity(0.6), // background color
  barrierDismissible: false, // should dialog be dismissed when tapped outside
  barrierLabel: "Dialog", // label for barrier
  transitionDuration: Duration(milliseconds: 400), // how long it takes to popup dialog after button click
  pageBuilder: (_, __, ___) { // your widget implementation 
    return SizedBox.expand( // makes widget fullscreen
      child: Column(
        children: <Widget>[
          Expanded(
            flex: 5,
            child: SizedBox.expand(child: FlutterLogo()),
          ),
          Expanded(
            flex: 1,
            child: SizedBox.expand(
              child: RaisedButton(
                color: Colors.blue[900],
                child: Text(
                  "Dismiss",
                  style: TextStyle(fontSize: 40),
                ),
                textColor: Colors.white,
                onPressed: () => Navigator.pop(context),
              ),
            ),
          ),
        ],
      ),
    );
  },
);
Run Code Online (Sandbox Code Playgroud)

  • @bloodloss 这只是您需要为语音辅助功能提供的强制字符串。 (3认同)
  • 太棒了:这个比其他答案要好。。。要知道,您要添加`barrierLabel`吗? (2认同)

Abd*_*tem 5

您可以将showGeneralDialog方法与任何扩展自 、 、 .. 等的小部件Material一起Scaffold使用Card

Scaffold例如,我将这样进行:

showGeneralDialog(
    context: context,
    pageBuilder: (context, animation, secondaryAnimation) => Scaffold(
      backgroundColor: Colors.black87,
      body: //Put your screen design here!
    ),
  );
Run Code Online (Sandbox Code Playgroud)

现在您可以使用 将您的设计设置为普通屏幕Scaffold

注意:如果您想返回,可以Navigator这样:

Navigator.of(上下文).pop(null)


om-*_*-ha 5

显示全屏对话框的不同方式

A. 材料对话

showDialog<void>(
  context: context,
  useSafeArea: false,
  builder: (BuildContext context) {
    return const SomeScaffoldView();
  },
);
Run Code Online (Sandbox Code Playgroud)

B. 库比蒂诺对话

showCupertinoDialog<void>(
  context: context,
  builder: (BuildContext context) {
    return const SomeScaffoldView();
  },
);
Run Code Online (Sandbox Code Playgroud)

C. 自定义对话框

showGeneralDialog(
  context: context,
  pageBuilder: (
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return const SomeScaffoldView();
  },
);
Run Code Online (Sandbox Code Playgroud)

上面片段中使用的示例脚手架视图。

class SomeScaffoldView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Sample Fullscreen Dialog'),
      ),
      body: const Center(child: Text('Dialog Body')),
    );
  }
}

Run Code Online (Sandbox Code Playgroud)


Fur*_*tas 5

在此输入图像描述

现在可以用Dialog.fullscreen它实现Material 3 的全屏对话框

有关PR问题的更多详细信息,请参阅。

这是DartPad 上的演示