Does Flutter support cascading grid style layouts such as:
You can create 4 Expanded in a Row and add Column of Containers in each Expanded:
Below is the code I ran and gives exact result you wish:
new Row(
children: <Widget>[
new Expanded(
child: new Column(
children: <Widget>[
new Container(
height: 50.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 24.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 150.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
],
),
),
new Expanded(
child: new Column(
children: <Widget>[
new Container(
height: 140.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 90.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 58.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
],
),
),
new Expanded(
child: new Column(
children: <Widget>[
new Container(
height: 20.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 220.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 50.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
],
),
),
new Expanded(
child: new Column(
children: <Widget>[
new Container(
height: 50.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 150.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
new Container(
height: 100.0,
color: Colors.grey,
margin: new EdgeInsets.all(10.0),
),
],
),
),
],
)
It gives the below result:
You can use a CustomScrollView or a SliderGrid with a custom gridDelegate
Related
My code is giving me the output what i required but there is one error which i need support to resolve.
RangeError (index): Invalid value: Valid value range is empty: 1
Below is the csv which i am using:
german word,german sentence,english word,english sentence
die Ansage,Hören Sie auf die Ansagen.,announcement,Listen to the announcements.
Here is the code:
I am getting error on line wher i am calling csvTable[index1+1][0],
class _CsvState extends State<Csv> {
#override
Widget build(BuildContext context, ) {
return FutureBuilder<String>(
future: rootBundle.loadString('assets/questions.csv'),
builder: (BuildContext context, AsyncSnapshot<String> snapshot,) {
List<List<dynamic>> csvTable =
CsvToListConverter().convert(snapshot.data);
return Scaffold(
appBar: AppBar(
title: Text("A1 German Vocabulary"),
),
body: new TransformerPageView (
itemCount: csvTable.length-1,
loop: true,
viewportFraction: 0.8,
itemBuilder: (BuildContext context, int index1) {
return new Padding(
padding: new EdgeInsets.all(10.0),
child: new Material(
elevation: 8.0,
textStyle: new TextStyle(color: Colors.white),
borderRadius: new BorderRadius.circular(10.0),
child: new Stack(
fit: StackFit.expand,
children: <Widget>[
new Positioned(
child: new Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
child: new Text(
csvTable[index1+1][0],
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
),
),
alignment: Alignment.center,
),
SizedBox(height: 20,),
new Container(
child: new Text(
csvTable[index1+1][1],
textAlign:TextAlign.center,
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
),
),
alignment: Alignment.center,
),
SizedBox(height: 20,),
new Container(
margin: const EdgeInsets.only(left: 10.0, right: 20.0),
child: Divider(
color: Colors.black,
height: 36,
)),
new Container(
child: new Text(
csvTable[index1+1][2],
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
height: 2
),
),
alignment: Alignment.center,
),
SizedBox(height: 20,),
new Container(
child: new Text(
csvTable[index1+1][3],
textAlign:TextAlign.center,
style: new TextStyle(
fontSize: 24.0,
color: Colors.black,
),
),
alignment: Alignment.center,
),
],
),
left: 10.0,
right: 10.0,
top: 100.0,
)
],
),
),
);
},
// itemCount:811
),
);
});
}
}
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.
The selection does not cover a set of statements or an expression. Extend selection to a valid range.
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Time Tracker'),
elevation: 3.0),
body: Container(
color: Colors.yellow,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
color: Colors.orange,
child: SizedBox(
width: 100.0,
height: 100.0,
),
),
Container(
color: Colors.red,
child: SizedBox(
width: 100.0,
height: 100.0,
),
),
Container(
color: Colors.purple,
child: SizedBox(
width: 100.0,
height: 100.0,
),
),
],
),
),
);
}
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 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>
),
);
});