Как сделать полноэкранный диалог во флаттера?

Я хочу сделать полноэкранное диалоговое окно. Фон диалогового окна должен быть непрозрачным. Вот пример: enter image description here

Как сделать так во Флаттере?

Ответ 1

Вы можете использовать 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'),
          ),
        ),
      ),
    );
  }
}

Ответ 2

Ну вот моя реализация, которая довольно проста.

с первого экрана

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.
.....
  );
 }
}

и вот результаты.

enter image description here

Ответ 3

Примечание. В этом ответе не обсуждается вопрос о том, как сделать модальную прозрачность, но это ответ на поставленный вопрос "Как сделать полноэкранный диалог во флаттере?". Надеюсь, это поможет другим, которые находят этот вопрос с помощью поиска, как я, которому не нужен прозрачный модал.

Создайте свой модальный класс диалога:

class SomeDialog extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: const Text('Dialog Magic'),
      ),
      body: new Text("It 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));
}

Ответ 4

Вывод (с использованием собственного диалогового окна флаттера)

enter image description here

Вот как вы можете показать диалог, используя встроенный метод флаттера 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

Это один из способов достижения этого:

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),
                  );
                }));
          },
        ),
      ),
    );
  }
}

Аналогичные результаты можно получить и с помощью виджета Stack.