答案 0 :(得分:27)
您可以使用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'),
),
),
),
);
}
}
答案 1 :(得分:9)
这是我的实现,非常简单。
从第一个屏幕
Navigator.of(context).push(PageRouteBuilder(
opaque: false,
pageBuilder: (BuildContext context, _, __) =>
RedeemConfirmationScreen()));
在第二个屏幕
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.
.....
);
}
}
这是结果。
答案 2 :(得分:2)
注意:此答案未讨论使模态透明,而是针对陈述的问题“如何在颤动中进行全屏对话框?”。希望这可以帮助其他人像我一样通过搜索找到该问题,并且不需要透明的模态。
创建模式对话框类:
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!"),
);
}
}
在需要打开对话框的类中,添加以下内容:
void openDialog() {
Navigator.of(context).push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
如果需要获取对话框操作的结果,请在对话框中添加一个按钮,该按钮会在弹出导航堆栈时返回一个值。像这样:
onPressed: () {
Navigator
.of(context)
.pop(new MyReturnObject("some value");
}
然后在您的班级中打开对话框,使用以下内容捕获结果:
void openDialog() async {
MyReturnObject results = await Navigator.of(context).push(new MaterialPageRoute<MyReturnObject>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
答案 3 :(得分:2)
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
insetPadding: EdgeInsets.zero,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0))),
content: SizedBox.expand(
child: Column(
children: <Widget>[
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: Wrap(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
flex: 1,
child: Text(
"Sample type",
style: TextStyle(fontWeight: FontWeight.w700),
),
),
Expanded(flex: 1, child: Text(""))
],
),
],
)),
],
),
));
});
},
);
答案 4 :(得分:1)
输出(使用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),
),
),
),
],
),
);
},
);
答案 5 :(得分:1)
您可以将 showGeneralDialog
方法与从 Material
扩展的任何小部件一起使用,例如 Scaffold
、Card
、..etc。
例如,我会像这样使用 Scaffold
:
showGeneralDialog(
context: context,
pageBuilder: (context, animation, secondaryAnimation) => Scaffold(
backgroundColor: Colors.black87,
body: //Put your screen design here!
),
);
现在您可以使用 Scaffold
将您的设计设置为普通屏幕。
注意:如果你想回去,你可以Navigator
这样:
Navigator.of(context).pop(null)
答案 6 :(得分:0)
RFlutter Alert是Flutter的超级可自定义且易于使用的警报/弹出对话框。您可以根据需要轻松创建可重复使用的警报样式或添加按钮。
Alert(context: context, title: "RFLUTTER", desc: "Flutter is awesome.").show();
易于使用! :)
答案 7 :(得分:0)
用 Navigator
小部件包裹您的顶级小部件,如下所示:
return Navigator(
pages: [
MaterialPage(
child: MainScreen(
child: widgets...
然后调用 showDialog 并且因为 useRootNavigator
默认设置为 true
它将使用我们在 MainScreen
上方添加的根导航器