Ich möchte ein Vollbild-Dialogfeld erstellen. Der Hintergrund des Dialogfelds muss undurchsichtig sein. Hier ist ein Beispiel:
Wie mache ich das in Flutter?
Sie können die Navigator
verwenden, um eine halbtransparente ModalRoute
zu verschieben:
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'),
),
),
),
);
}
}
Ausgabe (mit dem nativen Dialog von flattern)
Auf diese Weise können Sie den Dialog mit der in die Methode showGeneralDialog
eingebauten Flatterfunktion anzeigen. Rufen Sie diese Methode überall dort auf, wo Sie den Dialog anzeigen möchten.
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),
),
),
),
],
),
);
},
);
Hinweis: In dieser Antwort wird nicht darauf eingegangen, die Modalität transparent zu machen. Die Antwort lautet jedoch auf die Frage "Wie erstelle ich einen Vollbild-Dialog in Flattern?" Hoffentlich hilft das anderen, diese Frage durch eine Suche wie ich zu finden, die kein transparentes Modal benötigt.
Erstellen Sie Ihre modale Dialogklasse:
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!"),
);
}
}
Fügen Sie in der Klasse, die das Dialogfeld öffnen muss, Folgendes hinzu:
void openDialog() {
Navigator.of(context).Push(new MaterialPageRoute<Null>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
Wenn Sie das Ergebnis einer Dialogaktion abrufen müssen, fügen Sie Ihrem Dialogfeld eine Schaltfläche hinzu, die einen Wert zurückgibt, wenn Sie den Navigationsstapel öffnen. Etwas wie das:
onPressed: () {
Navigator
.of(context)
.pop(new MyReturnObject("some value");
}
wenn Sie dann in Ihrer Klasse das Dialogfeld öffnen, erfassen Sie die Ergebnisse mit einem der folgenden Werte:
void openDialog() async {
MyReturnObject results = await Navigator.of(context).Push(new MaterialPageRoute<MyReturnObject>(
builder: (BuildContext context) {
return new SomeDialog();
},
fullscreenDialog: true));
}
Dies ist eine Möglichkeit, dies zu erreichen:
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),
);
}));
},
),
),
);
}
}
Sie können ähnliche Ergebnisse auch mit dem Widget Stack
erzielen.
Nun, hier ist meine Implementierung, die recht einfach ist.
vom ersten Bildschirm
Navigator.of(context).Push(PageRouteBuilder(
opaque: false,
pageBuilder: (BuildContext context, _, __) =>
RedeemConfirmationScreen()));
auf dem zweiten Bildschirm
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.
.....
);
}
}
und hier sind die Ergebnisse.