Flutter - whitespaces displaying for image in portrait and landscape - flutter

I keep seeing lot of white space if I do landscape or portrait within my image. I do need the slidable so didn't want to tweak the code too much, but I do want it to look representable
is there something wrong with my code?
I did add a picture this is happening in both landscape and portrait mode
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text(
"1 Alif-laam-meem آلم, Pg2",
style: new TextStyle(color: styling.appBarTextcolor),
),
leading: new IconButton(
icon: new Icon(styling.appBarBackArrowIcon),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NavDrawer(),
));
})),
body: LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Stack(children: <Widget>[
new Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: styling.sizeofenglishandforward,
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,
child: new Container(
child: new Image.asset(
"test/assets/Para 1 - Alif-laam-meem no color/quranpg2-1.png",
// fit: BoxFit.fitidth,
fit: BoxFit.cover,
),
),
),
actions: <Widget>[
new IconSlideAction(
caption: styling.englishIconText,
color: styling.englishIconColorstripe,
icon: styling.englishIcon,
foregroundColor: styling.englishIconColor,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Changepg2topg2Color()),
);
}),
new IconSlideAction(
caption: styling.forwardIconText,
color: styling.forwardIconColorstripe,
icon: styling.forwardIcon,
foregroundColor: styling.forwardIconColor,
// onTap: () {
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => Changepg2topg3()),
// );
// }
),
// ),
],
secondaryActions: <Widget>[
new IconSlideAction(
caption: styling.backIconText,
color: styling.backIconColorstripe,
icon: styling.backIcon,
foregroundColor: styling.backIconColor,
// onTap: () => _showSnackBar('More'),
),
new IconSlideAction(
caption: styling.arabicIconText,
color: styling.arabicIconColorstripe,
icon: styling.arabicIcon,
foregroundColor: styling.arabicIconColor,
// onTap: () =>
),
],
),
]));
}));
}
}

SafeArea is preventing your image to go at some restricted areas of screen like, underneath the notch area. Or for some devices there are NavigationKeys in the bottom of screen. Try removing these
Cheers :)
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,

Related

Exception caught by rendering library A RenderFlex overflowed by 98349 pixels on the right. The relevant error-causing widget was AppBar

[hello, i'm doing this site and impractical what happens, everything goes except the app bar (from another error that is index out of range index is 0) this site is connected to firebase, the problem i think is there just that i don't know how solve it mainly because I have looked a lot of times that the collections on firebase had the right names but still does not go does anyone have a solution?]
CollectionReference userCollectionReference =
FirebaseFirestore.instance.collection('users');
CollectionReference bookCollectionReference =
FirebaseFirestore.instance.collection('books');
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white24,
elevation: 0.0,
toolbarHeight: 77,
centerTitle: false,
title: Row(
children: [
Text(
'A.Reader',
style: Theme.of(context).textTheme.headline6.copyWith(
color: Colors.redAccent, fontWeight: FontWeight.bold),
),
],
),
actions: [
StreamBuilder<QuerySnapshot>(
stream: userCollectionReference.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
final userListStream = snapshot.data.docs.map((user) {
return MUser.fromDocument(user);
}).where((user) {
return (user.uid == FirebaseAuth.instance.currentUser.uid);
}).toList(); //[user]
MUser curUser = userListStream[0];
print(userListStream);
return Column(
children: [
SizedBox(
height: 40,
width: 40,
child: InkWell(
child: CircleAvatar(
radius: 60,
backgroundImage: NetworkImage(
/* curUser.avatarUrl != null
? curUser.avatarUrl
: */
'https://i.pravatar.cc/300'),
backgroundColor: Colors.white,
child: Text(''),
),
onTap: () {
showDialog(
context: context,
builder: (context) {
// return createProfileMobile(context, userListStream,
// FirebaseAuth.instance.currentUser, null);
return createProfileDialog(context, curUser);
},
);
},
),
),
Text(
curUser.displayName.toUpperCase(),
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.black),
)
],
);
},
),
TextButton.icon(
onPressed: () {
FirebaseAuth.instance.signOut().then((value) {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
));
});
},
icon: Icon(Icons.logout),
label: Text(''))
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BookSearchPage(),
));
},
child: Icon(Icons.add),
backgroundColor: Colors.redAccent,
),
//error:
packages/flutter/src/widgets/async.dart 124:48 build
...
Exception caught by rendering library
A RenderFlex overflowed by 98349 pixels on the right.
The relevant error-causing widget was
AppBar
lib\screens\main_screen.dart:26
I think You Should write wrong code formatting try it out your code like below:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white24,
elevation: 0.0,
toolbarHeight: 77,
centerTitle: false,
title: Text(
'A.Reader',
style: Theme.of(context).textTheme.headline6.copyWith(
color: Colors.redAccent, fontWeight: FontWeight.bold),
),
),
body:StreamBuilder<QuerySnapshot>(
stream: userCollectionReference.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(),
);
}
final userListStream = snapshot.data.docs.map((user) {
return MUser.fromDocument(user);
}).where((user) {
return (user.uid == FirebaseAuth.instance.currentUser.uid);
}).toList(); //[user]
MUser curUser = userListStream[0];
print(userListStream);
return Column(
children: [
SizedBox(
height: 40,
width: 40,
child: InkWell(
child: CircleAvatar(
radius: 60,
backgroundImage: NetworkImage(
/* curUser.avatarUrl != null
? curUser.avatarUrl
: */
'https://i.pravatar.cc/300'),
backgroundColor: Colors.white,
child: Text(''),
),
onTap: () {
showDialog(
context: context,
builder: (context) {
// return createProfileMobile(context, userListStream,
// FirebaseAuth.instance.currentUser, null);
return createProfileDialog(context, curUser);
},
);
},
),
),
Text(
curUser.displayName.toUpperCase(),
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.black),
)
],
);
},
),
TextButton(
onPressed: () {
FirebaseAuth.instance.signOut().then((value) {
return Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage(),
));
});
},
icon: Icon(Icons.logout),
label: Text(''))
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => BookSearchPage(),
));
},
child: Icon(Icons.add),
backgroundColor: Colors.redAccent,
));
remove your StreamBuilder inside action[] of appbar and add it to the body of scaffold

Flutter - How can I reuse some code at multiple places

Hi I have a app where I will be making a book and this book will be with images,
I am trying to reuse code meaning how to add code within a method and than have that method at different areas but only change the image in each method .. .to make the code more reusable??? the code will stay the same but the image in each code block will change... i dont want to copy and paste the code again and again.
import 'dart:ui';
import 'package:adobe_xd/adobe_xd.dart';
import 'dart:io';
import 'package:Quran_highlighter/main.dart';
import 'package:flutter/rendering.dart';
import 'package:system_shortcuts/system_shortcuts.dart';
import 'package:Quran_highlighter/Widgets/NavDrawer.dart';
import 'package:flutter/material.dart';
import 'package:zoom_widget/zoom_widget.dart';
import 'package:flutter/gestures.dart';
import 'package:Quran_highlighter/Widgets/size_config.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
class Aliflaammeem extends StatefulWidget {
#override
_AliflaammeemState createState() => _AliflaammeemState();
}
class _AliflaammeemState extends State<Aliflaammeem> {
#override
Widget build(BuildContext context) {
var screenSizes = MediaQuery.of(context).size;
return Scaffold(
appBar: new AppBar(title: new Text("1 Alif-laam-meem آلم, Pg2")),
// return DefaultTextStyle(
// style: Theme.of(context).textTheme.bodyText2,
body: LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Stack(children: <Widget>[
new Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: 0.10,
// body: Center,
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,
child: new Container(
**child: new Image.asset(
"test/assets/Para 1 - Alif-laam-meem no color/quranpg2.png",**
fit: BoxFit.cover,
),
),
),
actions: <Widget>[
new IconSlideAction(
caption: 'English',
// color: Colors.lightBlue,
color: Colors.blueGrey,
icon: Icons.language,
foregroundColor: Colors.lightBlue,
// color: Colors.black,
// ),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Changepg2topg3()),
);
}),
new IconSlideAction(
caption: 'Forward',
// color: Colors.greenAccent,
// color: Colors.black87,
icon: Icons.arrow_back_ios,
foregroundColor: Colors.greenAccent,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Changepg2topg3()),
);
}),
// ),
],
secondaryActions: <Widget>[
new IconSlideAction(
caption: 'Back',
// color: Colors.red[200],
icon: Icons.arrow_forward_ios,
foregroundColor: Colors.red[200],
// color: Colors.black87,
// onTap: () => _showSnackBar('More'),
),
new IconSlideAction(
caption: 'Arabic',
// color: Colors.yellow[800],
icon: Icons.brightness_4,
foregroundColor: Colors.yellow[800],
color: Colors.blueGrey,
// onTap: () =>
),
],
),
]));
}));
}
}
//I WANT THE TOP CODE TO BE THE GLOBAL CODE WHICH WILL REUSED AGAIN AND
AGAIN IN THE SAME CLASS - AND IF I CHANGE SOMETHING UP THERE, I WANT IT TO AUTOMATICALLY CHANGE THROUGHOUT ALL THE PAGES
AND BELOW WE HAVE THE SAME CODE WHICH I COPIED AND PASTED - AND JUST CHANGED THE IMAGE AND APPBAR TITLE.... I NEED TO SEE HOW I CAN ACHIEVE THIS WITHOUT COPY AND PASTING....
class Changepg2topg3 extends StatelessWidget {
#override
Widget build(BuildContext context) {
var screenSizes = MediaQuery.of(context).size;
return Scaffold(
appBar: new AppBar(title: new Text("1 Alif-laam-meem آلم, Pg3")),
// return DefaultTextStyle(
// style: Theme.of(context).textTheme.bodyText2,
body: LayoutBuilder(builder:
(BuildContext context, BoxConstraints viewportConstraints) {
return SingleChildScrollView(
child: Stack(children: <Widget>[
new Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: 0.10,
// body: Center,
child: SafeArea(
top: true,
bottom: true,
right: true,
left: true,
child: new Container(
// padding: EdgeInsets.zero,
**child: new Image.asset(
`"test/assets/Para 1 - Alif-laam-meem no color/quranpg3.png",*`*
// fit: BoxFit.fitidth,
fit: BoxFit.cover,
),
),
),
actions: <Widget>[
new IconSlideAction(
caption: 'English',
color: Colors.lightBlue,
icon: Icons.language,
// onTap: () =>
),
new IconSlideAction(
caption: 'Forward',
color: Colors.greenAccent,
icon: Icons.arrow_back_ios,
// onTap: () => _showSnackBar('Share'),
),
],
secondaryActions: <Widget>[
new IconSlideAction(
caption: 'Back',
color: Colors.red[200],
icon: Icons.arrow_forward_ios,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Aliflaammeem()),
);
}),
// ),
new IconSlideAction(
caption: 'Arabic',
color: Colors.yellow[800],
icon: Icons.brightness_4,
// onTap: () =>
),
],
),
]));
// );
}));
}
}
// }
1.Make a class returning a list
2.Make a New Widget function and pass-in the list to this function

Flutter modal bottom sheet full height

I was trying things out with ModalBottomSheet. How can I achieve 90% height of device screen size for modal sheet. I did mediaquery but still it does not give me more than half of the screen size. How do I solve this?
Here is the code:
class _TestFileState extends State<TestFile> {
modalSheet() {
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
),
builder: (context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ListTile(
leading: Icon(Icons.email),
title: Text('Send email'),
onTap: () {
print('Send email');
},
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Call phone'),
onTap: () {
print('Call phone');
},
),
],
);
});
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Center(child: Text('Testing Modal Sheet')),
),
body: Center(
child: InkWell(
onTap: () {
modalSheet();
},
child: Container(
color: Colors.indigo,
height: 40,
width: 100,
child: Center(
child: Text(
'Click Me',
style: TextStyle(color: Colors.white),
),
)),
),
),
),
);
}
}
Here is the output:
you have to pass isScrollControlled: true and use mediaquery as given below
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return Container(
height: MediaQuery.of(context).size.height * 0.5,
color: Colors.red,
//height: MediaQuery.of(context).size.height,
);
});
As I remember that's a restriction about the native implementation of Flutter modal bottom sheet.
You can use the package modal_bottom_sheet to achieve that.
Install:
dependencies:
modal_bottom_sheet: ^0.2.2
And minimal example:
showMaterialModalBottomSheet(
context: context,
expand: true, //this param expands full screen
builder: (context, scrollController) => Container(),
)

flutter: how can I adjust the property of CupertinoAlertDialog?

I'm new in flutter. I want to adjust the dimensions and other properties like background color of the CupertinoAlertDialog. I have searched in the documents and tried some properties but didn't work. For background color example, I have tried to put it into a Container and set its color. Definitely it didn't work. So how can I achieve it? Thanks in advance.
Container(
color: Colors.red,
child: CupertinoAlertDialog(
title: Text('dropOut'), //对话框标题
content: SingleChildScrollView(
),
actions: [
CupertinoDialogAction(
child: Text('cancel'),
onPressed: () {},
),
CupertinoDialogAction(
child: Text('OK'),
onPressed: () {},
),
],
),
),
Edited: I tried the method suggested by #Salim Murshed, but it didn't seem work so well. here is my code and the display!
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
body: RaisedButton(
child: Text("Pick Me !!!"),
onPressed: () {
showDialog(
context: context,
builder: (_) => Center(
child: Container(
width: 270, height: 140,
color: Colors.red,
child: CupertinoAlertDialog (
title: new Text("Material Dialog"),
content: new Text("Hey! I'm Coflutter!"),
actions: <Widget>[
FlatButton(
child: Text('Close me!'),
onPressed: () {
Navigator.pop(_);
},
)
],
),
),
));
},
)
),
);
}
You can check the below code.
RaisedButton(
child: Text("Pick Me !!!"),
onPressed: () {
showDialog(
context: context,
builder: (_) => new AlertDialog(
title: new Text("Material Dialog"),
content: new Text("Hey! I'm Coflutter!"),
actions: <Widget>[
FlatButton(
child: Text('Close me!'),
onPressed: () {
Navigator.pop(_);
},
)
],
));
},
)

Display pop up menu when icon button widget is clicked Flutter

I have made an alert dialog where user can update their profile details. In that with image container there is icon button widget. What I want is that when user clicks icon button, pop up menu will display with add/remove image option. Here is my code for alert dialog:
showDialog<void>(
builder: (BuildContext context) {
return AlertDialog(
title: Text('Update details'),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
content: StatefulBuilder(
builder: (context, setState) { return Container(
width: 400,
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Stack(
alignment: Alignment.center,
children: [
Container(
width: 100.0,
height: 100.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.2), BlendMode.darken),
image: data != null ? MemoryImage(data) : AssetImage("web/icons/contactsDefaultImage.png")
)
)
),
IconButton(icon: Icon(Icons.edit), onPressed: () async {
//display option here
_showPopupMenu();
})
]),
Container(
child: TextFormField(
decoration: InputDecoration(
labelText: 'name'
),
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'email'
),
),
],
),
),
);},
),
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(child: Text('Save'),
onPressed: () {
// save
},
)
],
);
},
);
I tried to user showMenu for that. But as the position has to be hard-coded I don't was to use it.
what I tried:
void _showPopupMenu() async {
await showMenu(
context: context,
position: RelativeRect.fromLTRB(100, 100, 100, 100),
items: [
PopupMenuItem(
child: Text("add"),
),
PopupMenuItem(
child: Text("remove"),
),
],
elevation: 8.0,
);
}
Now, what i want to know is how can i display it where the icon-button is tapped (without hard-coding the value). And is there another way to do it .i.e without using showMenu.
You can write a method like this and call it on your icon button's onPressed
showPopupMenu(){
showMenu<String>(
context: context,
position: RelativeRect.fromLTRB(25.0, 25.0, 0.0, 0.0), //position where you want to show the menu on screen
items: [
PopupMenuItem<String>(
child: const Text('menu option 1'), value: '1'),
PopupMenuItem<String>(
child: const Text('menu option 2'), value: '2'),
PopupMenuItem<String>(
child: const Text('menu option 3'), value: '3'),
],
elevation: 8.0,
)
.then<void>((String itemSelected) {
if (itemSelected == null) return;
if(itemSelected == "1"){
//code here
}else if(itemSelected == "2"){
//code here
}else{
//code here
}
});
}
Edit: (to show menu at the position where user tapped)
We can have a method like so -
void showPopUpMenuAtTap(BuildContext context, TapDownDetails details) {
showMenu(
context: context,
position: RelativeRect.fromLTRB(
details.globalPosition.dx,
details.globalPosition.dy,
details.globalPosition.dx,
details.globalPosition.dy,
),
// other code as above
);
}
and use it with GestureDetector like so -
GestureDetector(
child: const Icon(Icons.menu),
onTapDown: (details) => showPopUpMenuAtPosition(context, details),
);
Solution if you wish to re-use your button and not a Gesture detector:
Create a key and assign your button the key. Then:
TextButton(
key: _accKey,
text: "Account",
onPressed: () {
final RenderBox renderBox =
_accKey.currentContext?.findRenderObject() as RenderBox;
final Size size = renderBox.size;
final Offset offset = renderBox.localToGlobal(Offset.zero);
showMenu(
context: context,
position: RelativeRect.fromLTRB(
offset.dx,
offset.dy + size.height,
offset.dx + size.width,
offset.dy + size.height),
items: [
PopupMenuItem<String>(
child: const Text('menu option 1'), value: '1'),
PopupMenuItem<String>(
child: const Text('menu option 2'), value: '2'),
PopupMenuItem<String>(
child: const Text('menu option 3'), value: '3'),
]);
}),
what you are looking to is showdialog and alertdialog.
Void<String> testdialog(BuildContext context) {
return showDialog(
barrierDismissible: false,
context: context,
builder: (context) {
return StatefulBuilder(builder: (context, setState) {
return AlertDialog(
title: ....
There are a lot of options you can choose:
You can use:
Banner
Card
Dialog
PopupMenuButton
Or even BottomSheet
I hope it will help