In my flutter code, I'm trying to make a layout constraint that can fit on multiple screen sizes but on my two emulators which one is 6" and the other is 10", the layout is either too small or too big. why? the layout contains one Column and four rows. the code below shows only the first row. I'd like the squares on the first row to fill in the space side to side automatically. the three bottom rows are hardcoded so disregard them. focused with your answer only on the first row.
here's the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
backgroundColor: Colors.deepOrangeAccent[100],
appBar: AppBar(
title: Center(child: Text('Kakuro SideKick III')),
backgroundColor: Colors.blueGrey[900],
),
body: Column(mainAxisAlignment: MainAxisAlignment.end,
//crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
print('Just clicked on 1');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('1'))),
),
GestureDetector(
onTap: () {
print('Just clicked on 2');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('2')),
),
),
GestureDetector(
onTap: () {
print('Just clicked on 3');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('3')),
),
),
GestureDetector(
onTap: () {
print('Just clicked on 4');
},
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 40.0,
minHeight: 40.0,
maxWidth: 150.0,
maxHeight: 150.0,
),
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('4')),
),
),
],
),
6" layout
10" Layout
To answer the question why is rather easy: you're setting explicit constraints (ie. min. and max. height/width), and the widgets cannot shrink/expand beyond that, so they (in most cases, anyway) either overflow the screen, or don't fill it.
What you're trying to achieve can be done using Expanded. If you want to retain the 1:1 aspect ratio, then use it in combination with AspectRatio.
Like so:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 1');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('1'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 2');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('2'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 3');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('3'))),
),
),
Expanded(
child: GestureDetector(
onTap: () {
print('Just clicked on 4');
},
child: AspectRatio(
aspectRatio: 1,
child: Container(
color: Colors.cyan,
padding: EdgeInsets.all(40.0),
margin: EdgeInsets.all(5.0),
child: Text('4'))),
),
),
],
)
Try to use MediaQuery instead a number, it looks like:
minWidth: MediaQuery.of(context).size.width
Exists two ways to use MediaQuery in this case:
MediaQuery.of(context).size.width (takes the whole width from the screen)
MediaQuery.of(context).size.height (the same, but for height)
You can make an calc with that, for exemple:
MediaQuery.of(context).size.width * 0.1 (10% from the whole width)
MediaQuery.of(context).size.height* 0.05 (5% from the whole height)
Try it.
Related
I am new to Android development. I am trying to stretch, 3 containers vertically and 3 containers horizontally using the row and column widget. Every time I add crossAxisAlignment: CrossAxisAlignment.stretch,inside my Row widget I get a BoxConstraints force an infinite height error.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Multichild Container Test'),
),
body: SafeArea(
child: Container(
child: Column(
children: <Widget>[
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.pink.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.green.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.deepPurple.shade900,
),
],
),
),
Container(
child: Row(
//crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.pink.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.green.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.deepPurple.shade900,
),
],
),
)
],
)
),
),
),
);
}
}
You can use copy paste run full code below
You can use Expanded and flex to provide height to Container
code snippet
Expanded(
flex: 1,
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Multichild Container Test'),
),
body: SafeArea(
child: Container(
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.pink.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.green.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.deepPurple.shade900,
),
],
),
),
),
Expanded(
flex: 1,
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.pink.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.green.shade900,
),
Container(
width: 60.0,
height: 100.0,
child: Text('Container 1'),
color: Colors.deepPurple.shade900,
),
],
),
),
)
],
)),
),
),
);
}
}
Red color one is carousal view
Green color one is horizontal ListView
Blue color one is Staggered Gridview widget
So My issue is Staggered Grid View is not srolling up inside Listview
I want to scroll all Content . Any one please help this . My code is :
**
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
physics: new AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
scrollDirection: Axis.vertical,
primary: true,
padding: EdgeInsets.symmetric(vertical: 50.0),
children: <Widget>[
CarouselSlider(
height: 180,
//height: double.infinity,
//aspectRatio: 16/9,
viewportFraction: 0.94,
initialPage: 0,
enlargeCenterPage: true,
autoPlay: false,
reverse: false,
enableInfiniteScroll: false,
scrollDirection: Axis.horizontal,
onPageChanged: (index) {
setState(() {
_current = index;
});
},
items: imgList.map((imgUrl) {
return Builder(
builder: (BuildContext context) {
return Container(
width: 400,
margin: EdgeInsets.all(2.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Image.network(
imgUrl,
fit: BoxFit.cover,
),
),
);
},
);
}).toList(),
),
SizedBox(
height: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: map<Widget>(imgList, (index, url) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: _current == index ? Colors.grey : Colors.black,
),
);
}),
),
Container(
padding: EdgeInsets.only(left: 15.0,bottom: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Latest Markers',textAlign: TextAlign.left ,overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22.0),)
],
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 0.0),
height: 100.0,
width: MediaQuery.of(context).size.width,
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemCount: latestList.length, itemBuilder: (context, index) {
return Container(
width: 100.0,
height: 100.0,
child: Card(
elevation: 3.0,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Align(
child: Image.network(latestList[index],fit: BoxFit.cover,width: 100.0,height: 100.0,),
),
),
),
);
}),
),
Container(
padding: EdgeInsets.only(left: 15.0,bottom: 10.0,top: 25.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('PlugXR Markers',textAlign: TextAlign.left ,overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22.0),)
],
),
),
Container(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 0.0),
height: MediaQuery.of(context).size.height,
child: StaggedWidget(),
),
)
],
)
);
}**
I tried putting a column in a row. But it does not work.
Then I tried putting the row and column in the same safe area using different child properties. It does not work.
The column is supposed to be in the middle of the row.
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.teal,
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
height: 100.0,
width: 100.0,
color: Colors.yellow,
child: Text('Container 1'),
),
Container(
height: 100.0,
width: 100.0,
color: Colors.green,
child: Text('Container 1'),
),
Container(
width: double.infinity,
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: 100.0,
color: Colors.red,
child: Text('Container 1'),
),
Container(
height: 100.0,
color: Colors.blue,
child: Text('Container 1'),
),
],
),
),
),
);
}
}
The error message is "BoxConstraints forces an infinite width."
Try expanded widget with flex attribute, you can put the column in a row:
Container(
width: 300,
height: 100,
child: Row(
children: <Widget>[
Expanded(flex: 1,
child: Container(
color: Colors.red,
width: double.infinity,
height: double.infinity,
),
),
Expanded(flex: 2,
child: Column(
children: <Widget>[
Expanded(flex:1,
child: Container(
color: Colors.yellow,
width: double.infinity,
height: double.infinity,
),
),
Expanded(flex:1,
child: Container(
color: Colors.blue,
width: double.infinity,
height: double.infinity,
),
),
],
),
),
Expanded(flex: 1,
child: Container(
color: Colors.green,
width: double.infinity,
height: double.infinity,
),
),
],
),
),
also, you can place column using a container
body: SafeArea(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
width: 100.0,
color: Colors.red,
),
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 100.0,
height: 100.0,
color: Colors.yellow,
),
Container(
width: 100.0,
height: 100.0,
color: Colors.green,
),
],
),
),
Container(
width: 100.0,
color: Colors.blue,
),
],
),
),
I created a container within another container within it. The child container is supposed to be smaller than the parent but this is not working. I only see the border of the child container.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(color: Colors.green),
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(color: Colors.red),
child: Card(
child: Text('fffff'),
),
),
),
);
}
you can use a Stack and a Positioned Widget for that like so:
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.blue,
),
child: Stack(
children: <Widget>[
Positioned(
left: 20.0,
top: 20.0,
child: Container(
height: 100,
width: 100,
decoration: BoxDecoration(color: Colors.green),
),
)
],
),
),
I am calling this dialog while getting data from server. This dialog box is having white spaces around it. I can I remove this white space around my dialog box. Here is my code.
var bodyProgress = new Container(
decoration: new BoxDecoration(
color: Colors.blue[200],
borderRadius: new BorderRadius.circular(10.0)
),
width: 300.0,
height: 200.0,
//color: Colors.blue,
alignment: AlignmentDirectional.center,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Center(
child: new SizedBox(
height: 50.0,
width: 50.0,
child: new CircularProgressIndicator(
value: null,
strokeWidth: 7.0,
),
),
),
new Container(
margin: const EdgeInsets.only(top: 25.0),
child: new Center(
child: new Text(
"Signing up...",
style: new TextStyle(
color: Colors.white
),
),
),
),
],
),
);
Here I am calling this dialog. I've tried with both AlertDialog() and SimpleDialog() having same issue with both.
showDialog(context: context, child: new AlertDialog(
content: bodyProgress,
));
Inside AlertDialog set contentPadding 0
contentPadding: EdgeInsets.zero,
make title to have Container, and add
width: MediaQuery.of(context).size.width,
Then give 0 (or what value you want to have for horizontal patting) to insetPadding like this:
insetPadding: EdgeInsets.symmetric(horizontal: 0),
Below is my example show dialog code, contains alertDialog with horizontal padding = 15 :
Future<void> _showLogoutDialog(BuildContext context) async {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
titlePadding: EdgeInsets.only(top: 12, left: 24, right: 12),
contentPadding: EdgeInsets.only(top: 12, left: 24, bottom: 20),
insetPadding: EdgeInsets.symmetric(horizontal: 15),
titleTextStyle: TextStyle(
color: ColorStyles.primary_blue500,
fontFamily: 'Muli',
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
fontSize: 16.0,
),
contentTextStyle: TextStyle(
color: ColorStyles.grey2,
fontFamily: 'Muli',
fontWeight: FontWeight.w400,
fontStyle: FontStyle.normal,
fontSize: 14.0,
),
title: Container(
width: screenUsableHeight(context),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('Log out'),
IconButton(
icon: Icon(
Icons.close,
color: ColorStyles.grey2,
size: 28,
),
onPressed: () => Navigator.of(context).pop(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
tooltip: "close",
)
],
),
),
//EN: Logging out
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Do you want to leave?'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text(
'Yes',
style: TextStyle(
color: ColorStyles.primary_blue500,
fontFamily: 'Muli',
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
fontSize: 16.0,
),
), //EN: Yes
onPressed: () {
_logOut(context);
},
),
FlatButton(
child: Text(
'No',
style: TextStyle(
color: ColorStyles.grey2,
fontFamily: 'Muli',
fontWeight: FontWeight.w500,
fontStyle: FontStyle.normal,
fontSize: 16.0,
),
), //EN: No
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
This looks like:
display of alert dialog
titlePadding: EdgeInsets.zero,
contentPadding: EdgeInsets.zero,
Don't use AlertDialog at all. Just send bodyProgress to showDialog
showDialog(context: context, builder: (_) => bodyProgress,);
add the file to your project https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/dialog.dart, use the CustomAlertDialog and set the contentPadding to 0.0 by using EdgeInsets.all(0.0), finally adjust the border raidius to that of your bodyprogress
use like this ->
using get: ------------->
Get.generalDialog(
pageBuilder: (BuildContext buildContext, Animation animation,
Animation secondaryAnimation) =>
AlertDialog(
contentPadding: EdgeInsets.zero,
// this padding user for outside of alert padding
insetPadding: EdgeInsets.symmetric(horizontal: 10),
content: Container(
height: Get.height - 300, // Change as per your requirement
width: Get.width, // Change as per your requirement
child: <Your Widget>
),
),
));
using alert dialog:------>
CustomAlertDialog(
content: new Container(
width: 260.0,
height: 230.0,
decoration: new BoxDecoration(
shape: BoxShape.rectangle,
color: const Color(0xFFFFFF),
borderRadius:
new BorderRadius.all(new Radius.circular(32.0)),
),
child: <Your widget>
),
);
});