Showing Dialog in nested MaterialApp - flutter - flutter

I'm using a nested MaterialApp such that, FirstMaterialApp has SecondMaterialApp as its child. I'm facing an issue when calling showDialog from SecondMaterialApp, that is it appears on the entire screen as if it is opened from the FirstMaterialApp.
I want that the dialog remains confined to the boundaries of the SecondMaterialApp.
In the image, I have intentionally stretched the Dialog across the width so that it is apparent that it covers the FirstMaterialApp.
First MaterialApp
class FirstMaterialApp extends StatelessWidget {
const FirstMaterialApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'First Material App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('First App Scaffold'),
),
body: Center(
child: DeviceFrame(
device: Devices.ios.iPhone12, screen: const SecondMaterialApp()),
));
}
}
Second MateriaApp
class SecondMaterialApp extends StatelessWidget {
const SecondMaterialApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Second Materia App', home: SecondScaffold());
}
}
class SecondScaffold extends StatelessWidget {
const SecondScaffold({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 40.0),
child: Scaffold(
appBar: AppBar(
title: const Text('Second App Home'),
),
body: Center(
child: TextButton(
child: const Text('Open Dialog'),
onPressed: () async {
await showDialog(
context: context,
builder: (buildContext) => CustomDialog());
},
),
),
),
);
}
}
class CustomDialog extends StatelessWidget {
const CustomDialog({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Dialog(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const [
Text(
'Dialog',
style: TextStyle(fontSize: 20.0),
),
Text(
'Message Text',
),
],
),
);
}
}

Found the solution by using a showDialog parameter named useRootNavigator. Setting it to false provided the required results.
Now the dialog is confined to the boundaries of child MaterialApp and the backgroundOverly from showDialog covers only the second material app.

-> use Your Second File code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SecondMaterialApp extends StatelessWidget {
const SecondMaterialApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Second Materia App', home: SecondScaffold());
}
}
class SecondScaffold extends StatelessWidget {
const SecondScaffold({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.only(top: 40.0),
child: Scaffold(
appBar: AppBar(
title: const Text('Second App Home'),
),
body: Center(
child: TextButton(
child: const Text('Open Dialog'),
onPressed: () async {
await showDialog(
context: context,
builder: (buildContext) => const CustomDialog());
},
),
),
),
);
}
}
class CustomDialog extends StatelessWidget {
const CustomDialog({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return CupertinoAlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: const \[
Text(
'Dialog',
style: TextStyle(fontSize: 20.0),
),
Text(
'Message Text',
),
\],
),
);
}
}

create material before dialog
return Material(child: Dialogue());

Related

Why is the refreshing pull in the App not working?

I'm building my app with Flutter 2.10.5 and Dart 2.16.2.
When i try to refresh the demo content whith a pull, nothing happens. I have multiple navigation routes for different content. So the demo is a litte bit complex.
The main.dart includes the basic code for the app. I use the NavDrawer Widget to build the different pages. Every route is defined in the navigation.dart file, which reference to the content widgets.
My code so far is:
import 'dart:core';
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() async {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of the application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo Company',
theme: ThemeData(),
debugShowCheckedModeBanner: false,
home: const HomePage(title: 'Demo Company'),
);
}
}
class _HomePageState extends State<HomePage> {
#override
initState() {
super.initState();
}
Widget _infoTile(String title, String subtitle) {
return ListTile(
title: Text(title),
subtitle: Text(subtitle.isEmpty ? 'Not set' : subtitle),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
drawer: const NavDrawer(),
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
_infoTile('App name', 'Demo App....'),
// Multiple Liste Tiles...
],
),
),
);
}
}
//----------------------------------------------------------------------
// navigation.dart
//----------------------------------------------------------------------
class NavDrawer extends StatelessWidget {
const NavDrawer({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Text(
'Navigation',
style: TextStyle(color: Colors.white, fontSize: 30),
),
SizedBox(height: 30.0),
Text('Firstname', style: TextStyle(color: Colors.black, fontSize: 15)),
Text('Accountname', style: TextStyle(color: Colors.black, fontSize: 15)),
],
),
),
ListTile(
leading: const Icon(Icons.notifications),
title: const Text('Demo'),
onTap: () {
Navigator.push(
context,
Demo.route(),
);
},
),
// Multiple Navigation List Tiles...
],
),
);
}
}
//----------------------------------------------------------------------
// demo.dart
//----------------------------------------------------------------------
class HomePage extends StatefulWidget {
const HomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<HomePage> createState() => _HomePageState();
}
class Demo extends StatefulWidget {
const Demo({Key? key}) : super(key: key);
static Route route() {
return CupertinoPageRoute(builder: (_) => const Demo());
}
#override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
final _data = <WordPair>[];
#override
void initState() {
super.initState();
_data.addAll(generateWordPairs().take(20));
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Woolha.com Flutter Tutorial'),
),
body: _buildList(),
);
}
Widget _buildList() {
return RefreshIndicator(
onRefresh: _refreshData,
child: ListView.builder(
padding: const EdgeInsets.all(20.0),
itemBuilder: (context, index) {
WordPair wordPair = _data[index];
return _buildListItem(wordPair.asString, context);
},
itemCount: _data.length,
),
);
}
Widget _buildListItem(String word, BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(word),
),
);
}
Future _refreshData() async {
await Future.delayed(const Duration(seconds: 3));
_data.clear();
_data.addAll(generateWordPairs().take(20));
setState(() {});
}
}
class ShowMessages extends StatelessWidget {
final String type;
final Color color;
const ShowMessages({Key? key, required this.type, required this.color}) : super(key: key);
#override
Widget build(BuildContext context) {
return ListView(
//color: color,
physics: const AlwaysScrollableScrollPhysics(),
children: [
ListTile(
title: Text(
type,
style: Theme.of(context).textTheme.bodyText1,
),
),
]);
}
}
Copy this code to DartPad
What is wrong?
Well for me this code... works
I copied it into Dartpad, then Dev Tools in browser (F12) > Device Emulation > Responsive. And you can use pull to refresh.
Of course this doesn't work using web view and mouse. I believe this gesture is not supported.

How to Make half screen like google assistant in flutter

Like this half screen
How can I achieve it in flutter? Please guide me in making this
many thanks for considering my request.
These are called bottom sheets. Please try the code below.
Bottom Sheet
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatelessWidget(),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return Container(
height: 200,
color: Colors.amber,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Text('Modal BottomSheet'),
ElevatedButton(
child: const Text('Close BottomSheet'),
onPressed: () => Navigator.pop(context),
)
],
),
),
);
},
);
},
),
);
}
}

ListView.builder inside a Column inside a SingleChildScrollView

all. I am trying to add a ListView.builder to a Column that is inside a SingleChildScrollView. However, I am getting an exception, likely due to the fact that there is no constraint for the ListView.builder. Here is my code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ListView.builder(
itemBuilder: (context, index) => const Text('a'),
itemCount: 2,
),
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
If I use a Container and set a defined height, the code above works. However, I am trying to get the ListView.builder to not have a fixed size. I've tried using the Expanded widget and I still get this error. Is there a way to make this work without a defined height? Thanks
In the column widget add mainAxisSize:MainAxisSize.min and in List view.builder add shrinkWrap:true and physics:NeverScrollablePhysics(). That should solve the issue and instead of center widget use SafeArea or a container with specific height.
Here's your working code
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ListView.builder(
shrinkWrap:true,// -> Add this here
physics:NeverScrollablePhysics(),// -> And this one
itemBuilder: (context, index) => const Text('a'),
itemCount: 2,
),
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}

Why I still got error functio at flutter?

Why I still got error functio at flutter?
I'd removed the old function and used new function, but it was still got old function.
In my main.dart, I tried to called LoginScreen
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'yocamp',
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: mobileBackgroundColor,
),
home: LoginScreen(),
);
}
}
But it was called MobileScreenLayout
home: const ResponsiveLayout(
mobileScreenLayout: MobileScreenLayout(),
webScreenLayout: WebScreenLayout(),
),
In my LoginScreen
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 32),
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//sva image
SvgPicture.asset(
'assets/yocampLogo.svg',
//color: primaryColor,
height: 64,
),
const SizedBox(height: 64),
//text field input for email
//text field input for password
//button login
//Transitioning to singing up
],
),
),
));
}
}
in the MobileScreenLayout
class MobileScreenLayout extends StatelessWidget {
const MobileScreenLayout({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('This is mobile'),
));
}
}
I want to show svg, but it's still show This is mobile
where has problems?

How can I show a floating button over all pages in Flutter?

I would like to keep showing a floating button or widget in Flutter even though the page is changed by Navigator.of(context).push() like mini music player which placed in the bottom.
How can I implement that ??
You can extract the scaffold as a layout that contains a bottom sheet, and use this layout in every page you build, passing in the title, body, etc., so that the bottom sheet is persistent in all pages. Snippet below.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Persistent Bottom Sheet',
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.dark,
),
initialRoute: "/",
routes: {
"/": (context) => Home(),
"/library": (context) => Library(),
},
);
}
}
class Home extends StatelessWidget {
Home({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Layout(
title: "Home",
body: Center(
child: Text("Home"),
),
actions: <Widget>[
InkWell(
onTap: () {
Navigator.of(context).pushNamed("/library");
},
child: Tooltip(
message: "Go To Library",
child: Padding(
padding: const EdgeInsets.all(12),
child: Icon(Icons.library_music),
),
),
)
],
);
}
}
class Library extends StatelessWidget {
Library({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Layout(
title: "Library",
body: Center(
child: Text("Library"),
),
);
}
}
class Layout extends StatelessWidget {
final String title;
final Widget body;
final List<Widget>? actions;
const Layout({
Key? key,
required this.title,
required this.body,
this.actions,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(title),
actions: actions,
),
body: body,
bottomSheet: Container(
width: double.infinity,
padding: const EdgeInsets.all(15),
color: Theme.of(context).cardColor,
child: Text("Persistent Bottom Sheet"),
),
);
}
}