Je veux créer une boîte de dialogue en plein écran. L'arrière-plan de la boîte de dialogue doit être opaque. Voici un exemple:
Comment faire comme ça dans Flutter?
Vous pouvez utiliser la Navigator
pour pousser un semi-transparent 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'),
),
),
),
);
}
}
Remarque: cette réponse ne traite pas de la transparence du modal, mais est une réponse à la question "Comment créer un dialogue en plein écran en mode Flutter?". J'espère que cela aidera les autres qui trouvent cette question grâce à une recherche comme moi, qui n'ont pas besoin d'un modal transparent.
Créez votre classe de dialogue modale:
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!"),
);
}
}
Dans la classe devant ouvrir la boîte de dialogue, ajoutez quelque chose comme ceci:
void openDialog() {
Navigator.of(context).Push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
Si vous devez obtenir le résultat d'une action de la boîte de dialogue, ajoutez à la boîte de dialogue un bouton qui renvoie une valeur lors du vidage de la pile de navigation. Quelque chose comme ça:
onPressed: () {
Navigator
.of(context)
.pop(new MyReturnObject("some value");
}
puis, dans votre classe qui ouvre la boîte de dialogue, capturez les résultats avec quelque chose comme:
void openDialog() async {
MyReturnObject results = await Navigator.of(context).Push(new MaterialPageRoute<MyReturnObject>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
C'est un moyen d'y parvenir:
void main() {
runApp(MaterialApp(home: MyScreen()));
}
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
child: Text('Show Overlay'),
onPressed: () {
Navigator.of(context).Push<Widget>(PageRouteBuilder<Widget>(
opaque: true,
transitionDuration: Duration(days: 1),
pageBuilder: (BuildContext context, _, __) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.call_to_action,color: Colors.white,),
],
),
color: Colors.black.withOpacity(0.90),
);
}));
},
),
),
);
}
}
Vous pouvez obtenir des résultats similaires en utilisant également le widget Stack
.
Eh bien voici ma mise en œuvre qui est assez simple.
à partir du premier écran
Navigator.of(context).Push(PageRouteBuilder(
opaque: false,
pageBuilder: (BuildContext context, _, __) =>
RedeemConfirmationScreen()));
au 2ème écran
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.
.....
);
}
}
et voici les résultats.